leg.v
来自「verilog hdl编写,六段流水线CPU.程序完整」· Verilog 代码 · 共 1,311 行 · 第 1/5 页
V
1,311 行
assign d_op_decoded_cmn = (d_op_opcode == 4'b1011) ? 1'b1 : 1'b0; //compare negated |upgrade flags after rn + shifter_oprand
assign d_op_decoded_orr = (d_op_opcode == 4'b1100) ? 1'b1 : 1'b0; //logical inclusive or |rd = rn | shifter_operand
assign d_op_decoded_mov = (d_op_opcode == 4'b1101) ? 1'b1 : 1'b0; //move |rd = shifter_operand
assign d_op_decoded_bic = (d_op_opcode == 4'b1110) ? 1'b1 : 1'b0; //bit clear |rd = rn and not(shifter_operand)
assign d_op_decoded_mvn = (d_op_opcode == 4'b1111) ? 1'b1 : 1'b0; //move not |rd = not(shifter_operand)
assign d_op_decoded_mul = (d_inst[27:21] == 7'b0000000 && d_inst[7:4] == 4'b1001) ? 1'b1 : 1'b0; //SHORT MULTIPLY
//dsp inst
assign d_op_deocded_mult_long = (d_inst[27:21] == 7'b0000110 && d_inst[7:4] == 4'b1001) ? 1'b1 : 1'b0; //long MULTIPLY
assign d_op_deocded_mult_accm = (d_inst[27:21] == 7'b0000001 && d_inst[7:4] == 4'b1001) ? 1'b1 : 1'b0; //multiply and accumulaton
//load /store decoding
assign d_op_decoded_ar = (d_inst[27:26] == 2'b00) ? 1'b1 : 1'b0;
assign d_op_decoded_ldr = (d_inst[27:26] == 2'b01 && d_inst[20] == 1) ? 1'b1 : 1'b0;
assign d_op_decoded_str = (d_inst[27:26] == 2'b01 && d_inst[20] == 0) ? 1'b1 : 1'b0;
assign d_op_decoded_ls_b_or_w = ((d_op_decoded_ldr || d_op_decoded_str) && d_inst[22]) ? 1'b1 : 1'b0; //1 means byte and 0 means word or not a load or store
assign d_op_decoded_ls_u = ((d_op_decoded_ldr || d_op_decoded_str) && !d_inst[23]) ? 1'b1 : 1'b0; //1 means subtract and 0 means add or not a load or store
assign d_op_decoded_ls_p = ((d_op_decoded_ldr || d_op_decoded_str) && ((!d_inst[24] && !d_inst[21]) || (d_inst[24] && d_inst[21]))) ? 1'b1 : 1'b0; //1 means update rn and 0 means do not update or not a load or store
assign d_op_decoded_ls_pre_addr= ((d_op_decoded_ldr || d_op_decoded_str) && !d_inst[24] && !d_inst[21]) ? 1'b1 : 1'b0;
//branch and link
assign d_op_decoded_br = (d_inst[27:25] == 3'b101 || d_op_decoded_swi) ? 1'b1 : 1'b0;
assign d_op_decoded_addr_ext = (d_inst[23]) ? {8'b11111111, d_inst[23:0]} : {8'b00000000, d_inst[23:0]};
assign d_op_decoded_br_l_bit = d_inst[24];
//software interrupt
assign d_op_decoded_swi = (d_inst[27:24] == 4'b1111)? 1'b1 : 1'b0;
assign d_op_decoded_undefined = (d_inst[27:23] == 5'b00110 && d_inst[21:20] == 2'b00 ||
d_inst[27:25] == 3'b011 && d_inst[4] == 1'b1 ||
d_inst[31:27] == 5'b11110 ||
d_inst[31:25] == 7'b1111100 ||
d_inst[31:24] == 8'b11111111)? 1'b1 : 1'b0;
assign d_op_decoded_msr = (d_inst[27:26] == 2'b00 && d_inst[24:23] == 2'b10 && d_inst[21:20] == 2'b10)? 1'b1 : 1'b0;
assign d_op_decoded_mrs = (d_inst[27:23] == 5'b00010 && d_inst[21:20] == 2'b00) ? 1'b1 : 1'b0;
assign d_op_deocded_msr_mask_c = (d_inst[19])? 8'hff : 8'h00;
assign d_op_deocded_msr_mask_x = (d_inst[18])? 8'hff : 8'h00;
assign d_op_deocded_msr_mask_s = (d_inst[17])? 8'hff : 8'h00;
assign d_op_deocded_msr_mask_f = (d_inst[16])? 8'hff : 8'h00;
assign d_op_deocded_msr_mask = {d_op_deocded_msr_mask_c, d_op_deocded_msr_mask_x, d_op_deocded_msr_mask_s, d_op_deocded_msr_mask_f};
assign d_op_decoded_msr_r_bit = d_inst[22];
assign d_op_decoded_mrs_r_bit = d_inst[22];
//foward enable
assign d_foward_ena = (d_op_rd == f_op_rn && d_valid && f_inst[27:26] != 2'b10)? 1'b1 : 1'b0;
assign d_ar_load_r15 = (!d_op_decoded_br && d_op_decoded_ar && d_op_rd == 15 && d_write_porta_ena)? 1'b1 : 1'b0;
//rf write enable for arithmetic, load, store
//port a is used for arithmetic and short mul and link addr and load store post addr
assign d_write_porta_ena = ((d_valid &&((d_inst[27:26] == 2'b00 && d_op_decoded_cmp == 0 && d_op_decoded_cmn == 0 && d_op_decoded_tst == 0 && d_op_decoded_teq == 0 && d_op_deocded_mult_accm == 0) || //arithmetic
//(d_inst[27:26] == 2'b01 && d_inst[4] == 0 && d_op_decoded_ls_p) ||
(d_inst[27:26] == 2'b01 && d_op_decoded_ls_p) || //what does the d_inst[4] means? //load store post addr
(d_op_decoded_br && d_op_decoded_br_l_bit) ||
(d_op_decoded_mrs) || //move cpsr also need a write //branch link addr
d_op_decoded_swi)) ||
d_lsm_restore_rd_valid )? 1'b1 : 1'b0; //software interrupt return addr
assign d_write_portb_ena = (d_valid && (d_inst[27:26] == 2'b01 && d_inst[20]) || //load
//(d_valid && (d_inst[27:26] == 2'b01 && d_inst[20] && d_inst[4] == 0) || //seems misunderstanding the load inst
d_op_deocded_mult_long || d_op_deocded_mult_accm) ? 1'b1 : 1'b0; //long mult and multiply and accumulation
//----------------------------------shifter operation
assign d_shift_by_register = (!d_inst[7] && d_inst[4]) ? 1'b1 :1'b0; //not full decoded
//barrier shifter
assign shifter_opcode = (!d_inst[25] && (d_op_decoded_ldr || d_op_decoded_str || d_op_deocded_mult_accm)) ? 5'b0 : (d_inst[25]) ? {d_inst[11:8], 1'b0} : (d_shift_by_register) ? rf_rdatab[4:0] : d_inst[11:7]; //
assign shifter_oprand = (!d_inst[25] && (d_op_decoded_ldr || d_op_decoded_str)) ? {20'h0,d_op_immediate_ls} : (d_inst[25]) ? {24'h0, d_inst[07:0]} : (rf_raddra_r == 15)? {2'b0, pc, 2'b0} : rf_rdataa;
//why I make such mistake??
//assign shifter_opcode = (!d_inst[25] && (d_op_decoded_ldr || d_op_decoded_str || d_op_deocded_mult_accm)) ? 5'b0 : (d_inst[25]) ? {d_inst[11:8], 1'b0} : (d_shift_by_register) ? rf_rdataa[4:0] : d_inst[11:7]; //
//assign shifter_oprand = (!d_inst[25] && (d_op_decoded_ldr || d_op_decoded_str)) ? {20'h0,d_op_immediate_ls} : (d_inst[25]) ? {24'h0, d_inst[07:0]} : (rf_raddra_r == 15)? {2'b0, pc, 2'b0} : rf_rdatab;
assign shifter_direction = (d_shifter_op_rotater_immd) ? 1'b0 : (d_inst[6:5] == 2'b00) ? 1'b1 : 1'b0;
//if the next inst will update the c flag by shifter result, carry in can use a foward result, otherwise it need a stall
assign shifter_carry_in = (!r_op_decoded_carry_from_arithm && r_op_s_bit) ? shifter_carry_r : cpsr_c_o; //or the alu output?
assign d_shifter_op_logic_shiftl_by_immd = (d_inst[6:4] == 3'b000) ? 1'b1 : 1'b0;
assign d_shifter_op_logic_shiftr_by_immd = (d_inst[6:4] == 3'b010) ? 1'b1 : 1'b0;
assign d_shifter_op_arthm_shiftr_by_immd = (d_inst[6:4] == 3'b100) ? 1'b1 : 1'b0;
assign d_shifter_op_rotater_by_immd = (d_inst[6:4] == 3'b110 && d_inst[11:7] != 5'b00000) ? 1'b1 : 1'b0;
assign d_shifter_op_rotater_immd = (d_inst[27:25] == 3'b001);
assign d_shifter_op_logic_shiftl_by_regd = (!d_inst[25] && d_inst[7:4] == 4'b0001) ? 1'b1 : 1'b0;
assign d_shifter_op_logic_shiftr_by_regd = (!d_inst[25] && d_inst[7:4] == 4'b0011) ? 1'b1 : 1'b0;
assign d_shifter_op_arthm_shiftr_by_regd = (!d_inst[25] && d_inst[7:4] == 4'b0101) ? 1'b1 : 1'b0;
assign d_shifter_op_rotater_by_regd = (!d_inst[25] && d_inst[7:4] == 4'b0111) ? 1'b1 : 1'b0;
//for load and arithmetic, the decoding is different
assign d_shifter_op_rotater_with_ext = (((d_inst[25] == 0 && d_op_decoded_ar) || (d_inst[25] == 1 && (d_op_decoded_ldr || d_op_decoded_str))) && d_inst[11:4] == 8'b00000110) ? 1'b1 : 1'b0;
assign shifter_mode = ((d_shifter_op_logic_shiftl_by_immd) ||
( d_shifter_op_logic_shiftl_by_regd)) ? 3'b000 :
((d_shifter_op_logic_shiftr_by_immd) ||
( d_shifter_op_logic_shiftr_by_regd)) ? 3'b001 :
((d_shifter_op_arthm_shiftr_by_immd) ||
( d_shifter_op_arthm_shiftr_by_regd)) ? 3'b010 :
((d_shifter_op_rotater_by_immd) ||
( d_shifter_op_rotater_by_regd) ||
(d_shifter_op_rotater_immd)) ? 3'b011 :
(d_shifter_op_rotater_with_ext) ? 3'b100 : 3'b000;
leg_shifter shifter_0(
.din(shifter_oprand),
.dout(shifter_result),
.shift_oprand(shifter_opcode),
.direction(shifter_direction),
.mode(shifter_mode),
.carry_in(shifter_carry_in),
.carry_out(shifter_carry_out)
);
always@(posedge clk or posedge rst)
begin
if (rst) begin
shifter_carry_r <= 1'b0;
rf_raddra_r <= 5'h0;
end
else begin
if (d_en) begin
shifter_carry_r <= shifter_carry_out;
rf_raddra_r <= rf_raddra;
end
end
end
//read the opranda
//control part
// there are some kinds of stall
// current read address rn == last write rd ----------------- cause 0 cycle stall by foward path
//done
// current read address rn == last load post write rn ------- cause 0 cycle stall by foward path
//done
// current read address rn == last store post write rn ------ cause 0 cycle stall by foward path
//done
// current read address rs or rm == last multipler result rl-- cause 1 cycle stall
//done
// current read address rs or rm == last multipler result rh-- cause 2 cycle stall
//done
// current read address rn == last multipler result rh------- cause 1 cycle stall
//done
// current read address rn == last multipler result rl------- cause 0 cycle stall
//done
// current read_address rs or rm == last accm result rd------- cause 2 cycle stall
//done
// current read_address rn == last accm result rd------------ cause 1 cycle stall
//done
// current shift with carry and last s bit ==1---------------- cause 1 cycle stall
//done
// load cpsr-------------------------------------------------- cause 4 cycle stall
// load/store multiple---------------------------------------- cause 18 cycle stall
assign d_op_decoded_carry_from_arithm = (d_op_decoded_adc || d_op_decoded_add || d_op_decoded_cmn || d_op_decoded_cmp || d_op_decoded_rsb || d_op_decoded_rsc || d_op_decoded_sub || d_op_decoded_sbc) ? 1'b1 : 1'b0 ;
assign d_ar_stall_d_shift_and_c_wait = (d_valid && d_op_s_bit && d_op_decoded_carry_from_arithm && d_op_s_bit && f_op_shift_rrx_pre);
wire d_msr_stall;
//d_ls_stall_drd_eq_frs: current read address rs or rm == last load rd ------------- cause 2 cycle stall
//d_ls_stall_drn_eq_frs: current read address rs or rm == last ls post write rn ---- cause 1 cycle stall
//d_ls_stall_drd_eq_frn: current read address rn == last load rd ----------------- cause 1 cycle stall
//d_ar_stall_drd_eq_frs: current read address rs or rm == last write rd------------- cause 1 cycle stall
//current is load and next is register and one of register equal
assign d_ls_stall_drd_eq_frs = (d_valid && (d_op_decoded_ldr) && (f_op_i_bit_pre && f_op_ls_pre || !f_op_i_bit_pre && f_op_ar_pre) && ((d_op_rd == f_op_rs_pre && f_op_rs_valid) || d_op_rd == f_op_rm_pre && f_op_rm_valid)) ? 1'b1 : 1'b0;
//current is load or store and need post writing and next is register and dfn = frs
assign d_ls_stall_drn_eq_frs = (d_valid && (d_op_decoded_ldr || d_op_decoded_str) && d_op_decoded_ls_p && (f_op_i_bit_pre && f_op_ls_pre || !f_op_i_bit_pre && f_op_ar_pre) && ((d_op_rn == f_op_rs_pre && f_op_rs_valid) || d_op_rn == f_op_rm_pre && f_op_rm_valid)) ? 1'b1 : 1'b0;
//current is load and
assign d_ls_stall_drd_eq_frn = (d_valid && (d_op_decoded_ldr) && (d_op_rd == f_op_rn_pre)) ? 1'b1 : 1'b0;
//current is arithmetic and next is register and
assign d_ar_stall_drd_eq_frs = (d_valid && d_op_decoded_ar && (f_op_i_bit_pre && f_op_ls_pre || !f_op_i_bit_pre && f_op_ar_pre) && ((d_op_rd == f_op_rs_pre && f_op_rs_valid) || d_op_rd == f_op_rm_pre && f_op_rm_valid)) ? 1'b1 : 1'b0;
assign d_msr_stall = (d_valid && d_op_decoded_msr)? 1'b1 : 1'b0;
assign d_stall = (f_lsm_state == 0 && (d_ls_stall_drd_eq_frs || d_ls_stall_drn_eq_frs || d_ls_stall_drd_eq_frn || d_ar_stall_drd_eq_frs || d_ar_stall_d_shift_and_c_wait || d_msr_stall)) ? 1'b1 : 1'b0;
//------------------------------------------------------------------------------end of decode stage
//------------------------------------------------------------------------------register stage
assign r_en = ~d_wait;
wire r_intr_exec;
assign r_intr_exec = ((irq_ena && irq_in) || (fiq_ena && fiq_in))? 1'b1 : 1'b0;
assign r_valid = (r_valid_r && a_br_exec == 1'b0 && w_load_r15 == 1'b0 && r_intr_exec == 1'b0)? 1'b1 : 1'b0;
//r_ls_stall_drd_eq_frs: current read address rs or rm == last load rd ------------- cause 1 cycle stall
//current is load and next is register and one of register equal
assign r_ls_stall_drd_eq_frs = (r_valid && ((r_op_decoded_ldr) && (f_op_i_bit_pre && f_op_ls_pre || !f_op_i_bit_pre && f_op_ar_pre) &&(r_op_rd == f_op_rs_pre && f_op_rs_valid || r_op_rd == f_op_rm_pre && f_op_rm_valid))) ? 1'b1 : 1'b0;
//accum or mult long
assign r_ar_accm_stall_drd_eq_frs = (r_valid && (r_op_deocded_mult_accm && (f_op_i_bit_pre && f_op_ls_pre || !f_op_i_bit_pre && f_op_ar_pre) && (r_op_rd == f_op_rs_pre && f_op_rs_valid || r_op_rd == f_op_rm_pre && f_op_rm_valid)));
assign r_ar_mull_stall_drh_eq_frs = (r_valid && (r_mult_long_r && (f_op_i_bit_pre && f_op_ls_pre || !f_op_i_bit_pre && f_op_ar_pre) && (r_op_rn == f_op_rs_pre && f_op_rs_valid || r_op_rn == f_op_rm_pre && f_op_rm_valid)));
assign r_stall = (!f_lsm_state && (r_ls_stall_drd_eq_frs || r_ar_accm_stall_drd_eq_frs || r_ar_mull_stall_drh_eq_frs));
reg [31:0] r_op_deocded_msr_mask;
reg r_op_deocded_msr;
reg r_op_decoded_mrs;
reg r_op_decoded_msr_r_bit;
reg r_op_decoded_mrs_r_bit;
reg r_op_decoded_undefined;
wire r_mode_err;
assign r_mode_err = (decoded_mode_user && r_op_deocded_msr) ? 1'b1 : 1'b0; //only msr need priviledge mode
//there will be no effect in user mode
wire [31:0] r_psr_reload_value;
wire [27:0] r_link_addr_pre;
assign r_link_addr_pre = (r_op_decoded_swi) ? d_link_addr : r_link_addr;
always@(posedge clk or posedge rst)
begin
if (rst) begin
r_op_rd <= 4'h0;
r_op_rn <= 4'h0;
end
else begin
if (r_en) begin
r_op_rd <= d_op_rd;
r_op_rn <= d_op_rn;
end
end
end
//register op
always@(posedge clk or posedge rst)
begin
if (rst) begin
r_inst <= 32'hffffffff;
end
else begin
if (r_en)
r_inst <= d_inst;
end
end
always@(posedge clk or posedge rst)
begin
if (rst) begin
r_valid_r <= 1'b0;
end
else begin
if (r_en)
r_valid_r <= d_valid;
end
end
always@(posedge clk or posedge rst)
begin
if (rst) begin
shift_result_r <= 32'h0;
end
else begin
if (r_en)
shift_result_r <= shifter_result;
end
end
always@(posedge clk or posedge rst)
begin
if (rst) begin
r_op_decoded_and <= 1'b0;
r_op_decoded_eor <= 1'b0;
r_op_decoded_sub <= 1'b0;
r_op_decoded_rsb <= 1'b0;
r_op_decoded_add <= 1'b0;
r_op_decoded_adc <= 1'b0;
r_op_decoded_sbc <= 1'b0;
r_op_decoded_rsc <= 1'b0;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?