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 + -
显示快捷键?