leg.v

来自「verilog hdl编写,六段流水线CPU.程序完整」· Verilog 代码 · 共 1,311 行 · 第 1/5 页

V
1,311
字号
//mode related
reg             decoded_mode_user;
reg             decoded_mode_fiq;
reg             decoded_mode_irq;
reg             decoded_mode_supervisor;
reg             decoded_mode_abort;
reg             decoded_mode_undefined;
reg             decoded_mode_system;

//intr input
assign          fiq_in = d_irq[1];
assign          irq_in = d_irq[0];


//cpsr decoding
always@(posedge clk or posedge rst)
begin
        if (rst) begin
                decoded_mode_user       <= 1'b0;
                decoded_mode_fiq        <= 1'b0;
                decoded_mode_irq        <= 1'b0;
                decoded_mode_supervisor <= 1'b0;
                decoded_mode_abort      <= 1'b0;
                decoded_mode_undefined  <= 1'b0;
                decoded_mode_system     <= 1'b0;                
        end
        else begin
                decoded_mode_user       <= (cpsr_m_o == 5'b10000) ? 1'b1 : 1'b0;
                decoded_mode_fiq        <= (cpsr_m_o == 5'b10001) ? 1'b1 : 1'b0;
                decoded_mode_irq        <= (cpsr_m_o == 5'b10010) ? 1'b1 : 1'b0;
                decoded_mode_supervisor <= (cpsr_m_o == 5'b10011) ? 1'b1 : 1'b0;
                decoded_mode_abort      <= (cpsr_m_o == 5'b10111) ? 1'b1 : 1'b0;
                decoded_mode_undefined  <= (cpsr_m_o == 5'b11011) ? 1'b1 : 1'b0;
                decoded_mode_system     <= (cpsr_m_o == 5'b11111) ? 1'b1 : 1'b0; 
        end
end
       

assign          cpsr_n_o                =       cpsr[31];
assign          cpsr_z_o                =       cpsr[30];
assign          cpsr_c_o                =       cpsr[29];
assign          cpsr_v_o                =       cpsr[28];
assign          cpsr_q_o                =       cpsr[27];       //not in use
assign          cpsr_dnm_o              =       cpsr[26:08];    //reserved
assign          cpsr_i_o                =       cpsr[07];
assign          cpsr_f_o                =       cpsr[06];
assign          cpsr_t_o                =       cpsr[05];
assign          cpsr_m_o                =       cpsr[04:00];        
assign          current_spsr            =       (decoded_mode_supervisor) ?     spsr_svc :
                                                (decoded_mode_abort)?           spsr_abt :
                                                (decoded_mode_undefined)?       spsr_und :
                                                (decoded_mode_irq)?             spsr_irq : spsr_fiq ;
assign          fiq_ena                 =       ~cpsr[6];       //fast interrupt enable bit
assign          irq_ena                 =       ~cpsr[7];       //normal interrupt enable bit

//code begins
//------------------------------------------------------------------------------fetch stage

//pc operation
always@(posedge clk or posedge rst)
begin
        if (rst) begin
                pc <= 28'h0;    //reset addr 
        end 
        else begin
                if (pc_reload) begin
                        pc <=  pc_reload_value;
                        `ifdef DEBUG_INFO
                                $display("now jump to addr %h",{2'b00,pc_reload_value,2'b00});
                        `endif 
                end
                else if (pc_en)
                        pc <=  pc + 28'h1;                        
        end
end 

always@(posedge clk or posedge rst)
begin
        if (rst) begin
                pc_reload_r <=  1'b0;
        end
        else begin
                if (f_en)
                        pc_reload_r <=  pc_reload;
        end
end



assign          pc_en           = (d_stall || r_stall || d_wait || i_wait || f_lsm_state || ((f_op_decoded_ldm || f_op_decoded_stm) && !(!f_lsm_state && f_lsm_state_d))) ? 1'b0 : 1'b1 ;             //fot alu test            //fot alu test
assign          pc_valid        = 1'b1;                 //for alu test
assign          pc_reload       = (((r_op_decoded_br || r_load_r15 || r_op_decoded_swi) && r_exec) || w_load_r15 || (fiq_ena && fiq_in) || (irq_ena && irq_in)) ? 1'b1 : 1'b0;
assign          pc_reload_value =  (r_load_r15)? r_alu_result[29:2] : (w_load_r15)? rf_wdatab[29:2] : (r_op_decoded_swi)? 28'h0000002 : (fiq_in && fiq_ena)? 28'h0000007 : (irq_ena && irq_in)? 28'h0000004 : {d_link_addr + r_op_decoded_addr_ext};          //pc aligned with word boundary
assign          i_addr = (pc_valid) ? {2'b00, pc, 2'b00} : 32'h00000000;
//end of pc 
  
//-----------------------------------f stage
assign          f_en    = ~d_wait; 
assign          f_inst  = (f_lsm_state) ? f_lsm_inst : (f_stall) ? f_inst_backup : i_datain;             // (d_stall || r_stall)? 32'hf29cc000 : for further processing
assign          f_op_rm_pre = i_datain[03:00];
//stall inst use the rs as the rn port
assign          f_op_rs_pre = (f_op_ls_pre && i_datain[20] == 1'b0) ? i_datain[15:12] : i_datain[11:08];
assign          f_op_rn_pre = i_datain[19:16];
assign          f_op_ls_pre = (i_datain[27:26] == 2'b01) ? 1'b1 : 1'b0;
assign          f_op_ar_pre = (i_datain[27:26] == 2'b00) ? 1'b1 : 1'b0; 
assign          f_op_i_bit_pre = i_datain[25];
assign          f_op_s_bit_pre = i_datain[20];
assign          f_op_p_bit_pre = i_datain[24];
assign          f_op_rs_bit_pre = i_datain[4];
assign          f_op_shift_rrx_pre = (i_datain[11:04] == 8'b00000110) ? 1'b1 : 1'b0;
assign          f_op_mrs_pre = (i_datain[27:23] == 5'b00010 && i_datain[21:20] == 2'b00) ? 1'b1 : 1'b0;
assign          f_op_rm_valid = (!f_op_mrs_pre && !f_op_i_bit_pre) ? 1'b1 : 1'b0;
assign          f_op_rs_valid = (!f_op_mrs_pre && !f_op_i_bit_pre && f_op_rs_bit_pre) ? 1'b1 : 1'b0;
assign          f_op_rm = f_inst[03:00];
assign          f_op_rn = f_inst[19:16];
assign          f_op_rd = f_inst[15:12];
//there 's only read 3 ports for the register file, so the store will use rd as a 
//read address, it's very lucky the address mode has no rs, so just use rd instead rs
assign          f_op_rs = (f_op_str) ? f_inst[15:12] : f_inst[11:08];   //if is a store inst, use rd instead of rn.
//assign          f_op_rs = f_inst[11:08];
assign          f_op_str= (f_inst[27:26] == 2'b01 && f_inst[20] == 1'b0) ? 1'b1 : 1'b0;
//does it need f_stall?
assign          i_cache_data_valid = (i_wait && !f_stall)? 1'b0 : 1'b1;        //f_stall then the data is not from i cache, so the data valid is not controlled by i_wait;
assign          f_valid = (i_cache_data_valid && !d_stall && !r_stall && !pc_reload_r && !pc_reload && !f_op_decoded_ldm && !f_op_decoded_stm && !f_lsm_state && !f_lsm_state_d || (f_lsm_state && f_lsm_generated_inst_valid)) ? 1'b1 : 1'b0;              //not completed implement yet
assign          f_op_decoded_br = (f_inst[27:25] == 3'b101) ? 1'b1 : 1'b0;              //branch instrution
assign          f_op_decoded_br_l_bit = f_inst[24];

//note: cpsr mode change must stall for 4 cycle for all the mode correct.
always@(posedge clk or posedge rst)
begin
        if (rst) begin
                f_stall <=  1'b0;
        end
        else begin
                if (f_en)
                        f_stall <=  d_stall | r_stall | f_lsm_state;
        end
end

always@(posedge clk or posedge rst)
begin
        if (rst) begin
                f_inst_backup <=  32'h0;
        end
        else begin
                if (f_en) begin
                        if (d_stall || r_stall || f_op_decoded_ldm || f_op_decoded_stm)
                                f_inst_backup <=  i_datain;
                end
        end
end

//what if f_stall?
always@(posedge clk or posedge rst)
begin
        if (rst) begin
                i_read <=  1'b1;
        end
        else begin
                if (f_en)
                        i_read <= (!i_wait) ? 1'b1 : 1'b0;
        end
end

always@(posedge clk or posedge rst)
begin
        if (rst) begin
                i_read_d <=  1'b0;
        end
        else begin
                if (f_en)
                        i_read_d <=  (i_read && !i_wait);
        end
end

always@(posedge clk or posedge rst)
begin
        if (rst) begin
                d_link_addr <=  28'h0;
        end
        else begin
                if (d_en)
                        d_link_addr <= pc;
        end
end


//read before decoder stage       
//note: undefined mode are not implemented!! 
assign          f_op_decoded_raddra = (decoded_mode_fiq &&  f_op_rm[3])  ? {{1'b0, f_op_rm} + 4'h8} :     //fiq high 8 registers 
                            (decoded_mode_irq &&  f_op_rm == 4'd13)  ? 5'd24 :
                            (decoded_mode_irq &&  f_op_rm == 4'd14)  ? 5'd25 :
                            (decoded_mode_supervisor && f_op_rm == 4'd13) ? 5'd26 :
                            (decoded_mode_supervisor && f_op_rm == 4'd14) ? 5'd27 :
                            (decoded_mode_abort && f_op_rm == 4'd13) ? 5'd28 :
                            (decoded_mode_abort && f_op_rm == 4'd14) ? 5'd29 :
                            (decoded_mode_undefined && f_op_rm == 4'd13) ? 5'd30 :
                            (decoded_mode_undefined && f_op_rm == 4'd14) ? 5'd31 : {1'b0, f_op_rm}; //other registers

assign          f_op_decoded_raddrb = (decoded_mode_fiq &&  f_op_rs[3])  ? {{1'b0, f_op_rs} + 4'h8} :     //fiq high 8 registers 
                            (decoded_mode_irq &&  f_op_rs == 4'd13)  ? 5'd24 :
                            (decoded_mode_irq &&  f_op_rs == 4'd14)  ? 5'd25 :
                            (decoded_mode_supervisor && f_op_rs == 4'd13) ? 5'd26 :
                            (decoded_mode_supervisor && f_op_rs == 4'd14) ? 5'd27 :
                            (decoded_mode_abort && f_op_rs == 4'd13) ? 5'd28 :
                            (decoded_mode_abort && f_op_rs == 4'd14) ? 5'd29 :
                            (decoded_mode_undefined && f_op_rs == 4'd13) ? 5'd30 :
                            (decoded_mode_undefined && f_op_rs == 4'd14) ? 5'd31 : {1'b0, f_op_rs}; //other registers

assign          f_op_decoded_raddrc = (decoded_mode_fiq &&  f_op_rn[3])  ? {{1'b0, f_op_rn} + 4'h8} :     //fiq high 8 registers 
                            (decoded_mode_irq &&  f_op_rn == 4'd13)  ? 5'd24 :
                            (decoded_mode_irq &&  f_op_rn == 4'd14)  ? 5'd25 :
                            (decoded_mode_supervisor && f_op_rn == 4'd13) ? 5'd26 :
                            (decoded_mode_supervisor && f_op_rn == 4'd14) ? 5'd27 :
                            (decoded_mode_abort && f_op_rn == 4'd13) ? 5'd28 :
                            (decoded_mode_abort && f_op_rn == 4'd14) ? 5'd29 :
                            (decoded_mode_undefined && f_op_rn == 4'd13) ? 5'd30 :
                            (decoded_mode_undefined && f_op_rn == 4'd14) ? 5'd31 : {1'b0, f_op_rn}; //other registers


//pre porcessing of the load / store multiple



assign          f_lsm_rout = (f_lsm_inst_backup[20]) ? f_lsm_rlist[0] : f_lsm_rlist[15];

assign          f_lsm_inst[31:28]       = f_lsm_inst_backup[31:28];
assign          f_lsm_inst[27:25]       = 3'b010;
//update the base address at the end of operation
assign          f_lsm_inst[24]          = 1'b1;//(((f_lsm_counter == 0 && !f_lsm_inst_backup[20])||(f_lsm_counter == 4'hf && f_lsm_inst_backup[20])))? ~f_lsm_inst_backup[21] : 1'b1;
assign          f_lsm_inst[23]          = f_lsm_inst_backup[23];
assign          f_lsm_inst[22]          = 1'b0;
assign          f_lsm_inst[21]          = 1'b0;
assign          f_lsm_inst[20]          = f_lsm_inst_backup[20];
assign          f_lsm_inst[19:16]       = f_lsm_inst_backup[19:16];
assign          f_lsm_inst[15:12]       = (f_lsm_state == 3)? f_lsm_inst_backup[19:16] : f_lsm_counter[3:0];

//how about the address not include the base address?
assign          f_lsm_inst[11:0]        = (f_lsm_state == 3)? {6'h0,f_lsm_addr_counter_backup,2'h0} : {6'h0,f_lsm_addr_counter,2'h0}; 


//although the inst 15 maybe not valid , the last addr still need to be put into rf
//assign          f_lsm_restore_rd_valid = ((f_lsm_state == 1 || f_lsm_state == 2) && ((f_lsm_counter == 4'h0 && !f_lsm_inst_backup[20]) || (f_lsm_counter == 4'hf && f_lsm_inst_backup[20])) && f_lsm_inst_backup[21] == 1'b1)? 1'b1 : 1'b0; // w = 1 and condition passed 
assign          f_lsm_restore_rd_valid = (f_lsm_state == 3 && ((f_lsm_counter == 4'h0 && !f_lsm_inst_backup[20]) || (f_lsm_counter == 4'hf && f_lsm_inst_backup[20])) && f_lsm_inst_backup[21] == 1'b1)? 1'b1 : 1'b0; // w = 1 and condition passed 



always@(posedge clk or posedge rst)
begin
        if (rst) begin
                f_lsm_load_base_addr_r <= 1'b0;
                f_lsm_addr_counter_backup <= 4'h0;
        end
        else begin
                if (f_lsm_state == 1 && f_lsm_load_base_addr)
                        f_lsm_load_base_addr_r <= 1'b1;
                else if (f_lsm_state != 1)
                        f_lsm_load_base_addr_r <= 1'b0;
                if (f_lsm_load_base_addr) begin
                        f_lsm_addr_counter_backup <= f_lsm_addr_counter;
                end
        end
end

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?