diff options
| author | Alejandro Soto <alejandro@34project.org> | 2022-11-07 12:57:48 -0600 |
|---|---|---|
| committer | Alejandro Soto <alejandro@34project.org> | 2022-11-07 13:31:15 -0600 |
| commit | aaf02562e4d49fc93df1f619e3fbd6c85c0e7951 (patch) | |
| tree | d7ae1d53f18950d370def5932553947c3af4f785 /rtl/core | |
| parent | f78de55eef2e805e459064005daa08c7697d2273 (diff) | |
Implement multiplication control
Diffstat (limited to 'rtl/core')
| -rw-r--r-- | rtl/core/arm810.sv | 4 | ||||
| -rw-r--r-- | rtl/core/control/control.sv | 15 | ||||
| -rw-r--r-- | rtl/core/control/cycles.sv | 18 | ||||
| -rw-r--r-- | rtl/core/control/mul.sv | 55 | ||||
| -rw-r--r-- | rtl/core/control/select.sv | 7 | ||||
| -rw-r--r-- | rtl/core/control/writeback.sv | 45 | ||||
| -rw-r--r-- | rtl/core/decode/mul.sv | 2 | ||||
| -rw-r--r-- | rtl/core/decode/mux.sv | 3 | ||||
| -rw-r--r-- | rtl/core/mul.sv | 4 | ||||
| -rw-r--r-- | rtl/core/uarch.sv | 4 |
10 files changed, 119 insertions, 38 deletions
diff --git a/rtl/core/arm810.sv b/rtl/core/arm810.sv index 2cc35a8..3f237aa 100644 --- a/rtl/core/arm810.sv +++ b/rtl/core/arm810.sv @@ -134,7 +134,7 @@ module arm810 .c(c_shifter) ); - logic mul, mul_add, mul_long, mul_signed, mul_ready; + logic mul_start, mul_add, mul_long, mul_signed, mul_ready; word mul_a, mul_b, mul_c_hi, mul_c_lo, mul_q_hi, mul_q_lo; psr_flags mul_flags; @@ -147,7 +147,7 @@ module arm810 .long_mul(mul_long), .add(mul_add), .sig(mul_signed), - .start(mul), + .start(mul_start), .q_hi(mul_q_hi), .q_lo(mul_q_lo), .n(mul_flags.n), diff --git a/rtl/core/control/control.sv b/rtl/core/control/control.sv index 917dbf8..06978e6 100644 --- a/rtl/core/control/control.sv +++ b/rtl/core/control/control.sv @@ -21,6 +21,8 @@ module core_control mem_ready, input word mem_data_rd, input logic mul_ready, + input word mul_q_hi, + mul_q_lo, `ifdef VERILATOR input word insn, @@ -48,9 +50,13 @@ module core_control output word mem_data_wr, output logic mem_start, mem_write, - mul, - mul_add, + output word mul_a, + mul_b, + mul_c_hi, + mul_c_lo, + output logic mul_add, mul_long, + mul_start, mul_signed, coproc ); @@ -104,7 +110,10 @@ module core_control .* ); - core_control_data ctrl_mul + logic mul; + reg_num mul_r_add_hi, mul_r_add_lo; + + core_control_mul ctrl_mul ( .* ); diff --git a/rtl/core/control/cycles.sv b/rtl/core/control/cycles.sv index e9bc2da..fdf4ebe 100644 --- a/rtl/core/control/cycles.sv +++ b/rtl/core/control/cycles.sv @@ -8,6 +8,8 @@ module core_control_cycles bubble, exception, mem_ready, + mul_add, + mul_long, mul_ready, pop_valid, trivial_shift, @@ -21,10 +23,12 @@ module core_control_cycles always_comb begin next_cycle = ISSUE; - unique case(cycle) + unique0 case(cycle) ISSUE: if(exception) next_cycle = EXCEPTION; + else if(mul) + next_cycle = mul_add ? MUL_ACC_LD : MUL; else if(data_snd_shift_by_reg) next_cycle = RD_INDIRECT_SHIFT; else if(!trivial_shift) @@ -43,17 +47,17 @@ module core_control_cycles MUL: if(!mul_ready) next_cycle = MUL; + else if(mul_long) + next_cycle = MUL_HI_WB; - default: ; + MUL_ACC_LD: + next_cycle = MUL; endcase if(bubble) next_cycle = ISSUE; - else if(next_cycle == ISSUE) begin - if(ldst) - next_cycle = TRANSFER; - else if(mul) - next_cycle = MUL; + else if(next_cycle == ISSUE && ldst) begin + next_cycle = TRANSFER; end end diff --git a/rtl/core/control/mul.sv b/rtl/core/control/mul.sv index 8d23514..81fc120 100644 --- a/rtl/core/control/mul.sv +++ b/rtl/core/control/mul.sv @@ -7,29 +7,68 @@ module core_control_mul input datapath_decode dec, input mul_decode dec_mul, input logic mul_ready, + input word rd_value_a, + rd_value_b, - input ctrl_cycle next_cycle, + input ctrl_cycle cycle, + next_cycle, input logic issue, + output word mul_a, + mul_b, + mul_c_hi, + mul_c_lo, + output reg_num mul_r_add_hi, + mul_r_add_lo, output logic mul, mul_add, mul_long, + mul_start, mul_signed ); - always_ff @(posedge clk) - if(next_cycle == ISSUE && issue) begin - mul <= dec.mul; - mul_add <= dec_mul.add; - mul_long <= dec_mul.long_mul; - mul_signed <= dec_mul.signed_mul; - end + word hold_a, hold_b; + + assign {mul_c_hi, mul_c_lo} = {rd_value_a, rd_value_b}; + assign {mul_a, mul_b} = mul_add ? {hold_a, hold_b} : {rd_value_a, rd_value_b}; + + always_ff @(posedge clk) begin + mul_start <= 0; + + unique0 case(next_cycle) + ISSUE: + if(issue) begin + mul <= dec.mul; + mul_add <= dec_mul.add; + mul_long <= dec_mul.long_mul; + mul_signed <= dec_mul.signed_mul; + mul_r_add_hi <= dec_mul.r_add_hi; + mul_r_add_lo <= dec_mul.r_add_lo; + end + + MUL: + mul_start <= cycle != MUL; + + MUL_ACC_LD: begin + hold_a <= rd_value_a; + hold_b <= rd_value_b; + end + endcase + end + + //TODO: mul update_flags initial begin mul = 0; mul_add = 0; mul_long = 0; + mul_start = 0; mul_signed = 0; + mul_r_add_hi = {$bits(mul_r_add_hi){1'b0}}; + mul_r_add_lo = {$bits(mul_r_add_lo){1'b0}}; + + hold_a = 0; + hold_b = 0; end endmodule diff --git a/rtl/core/control/select.sv b/rtl/core/control/select.sv index ea9850b..46a16d7 100644 --- a/rtl/core/control/select.sv +++ b/rtl/core/control/select.sv @@ -14,6 +14,8 @@ module core_control_select pop_valid, input reg_num popped, final_rd, + mul_r_add_lo, + mul_r_add_hi, output reg_num ra, rb, @@ -40,6 +42,11 @@ module core_control_select if(cycle != TRANSFER || mem_ready) // final_rd viene de dec_ldst.rd rb <= pop_valid ? popped : final_rd; + + MUL_ACC_LD: begin + ra <= mul_r_add_hi; + rb <= mul_r_add_lo; + end endcase initial begin diff --git a/rtl/core/control/writeback.sv b/rtl/core/control/writeback.sv index 85b2f9f..6a0afc8 100644 --- a/rtl/core/control/writeback.sv +++ b/rtl/core/control/writeback.sv @@ -7,20 +7,23 @@ module core_control_writeback input datapath_decode dec, input psr_decode dec_psr, input data_decode dec_data, + input psr_flags alu_flags, + input word q_alu, + mem_data_rd, + input logic mem_ready, + mem_write, + input word mul_q_hi, + mul_q_lo, input ctrl_cycle cycle, next_cycle, input word saved_base, - mem_data_rd, vector, - q_alu, - input psr_flags alu_flags, input reg_num ra, popped, - input logic pop_valid, - issue, - mem_ready, - mem_write, + mul_r_add_hi, + input logic issue, + pop_valid, output reg_num rd, final_rd, @@ -45,6 +48,9 @@ module core_control_writeback EXCEPTION: rd <= `R15; + + MUL_HI_WB: + rd <= mul_r_add_hi; endcase unique0 case(next_cycle) @@ -74,7 +80,7 @@ module core_control_writeback BASE_WRITEBACK: writeback <= !mem_write; - EXCEPTION: + EXCEPTION, MUL_HI_WB: writeback <= 1; endcase @@ -86,12 +92,6 @@ module core_control_writeback final_writeback <= 1; endcase - unique case(cycle) - TRANSFER: wr_value <= mem_data_rd; - BASE_WRITEBACK: wr_value <= saved_base; - default: wr_value <= q_alu; - endcase - update_flags <= 0; unique0 case(next_cycle) ISSUE: @@ -109,6 +109,20 @@ module core_control_writeback final_update_flags <= 0; endcase + unique case(cycle) + TRANSFER: + wr_value <= mem_data_rd; + + BASE_WRITEBACK: + wr_value <= saved_base; + + MUL, MUL_HI_WB: + wr_value <= mul_q_lo; + + default: + wr_value <= q_alu; + endcase + unique0 case(next_cycle) TRANSFER: if(mem_ready) @@ -119,6 +133,9 @@ module core_control_writeback EXCEPTION: wr_value <= vector; + + MUL_HI_WB: + wr_value <= mul_q_hi; endcase end diff --git a/rtl/core/decode/mul.sv b/rtl/core/decode/mul.sv index 27f6651..114b65b 100644 --- a/rtl/core/decode/mul.sv +++ b/rtl/core/decode/mul.sv @@ -23,7 +23,7 @@ module core_decode_mul assign decode.add = insn `FIELD_MUL_ACC; assign decode.long_mul = long_mul; assign decode.signed_mul = insn `FIELD_MUL_SIGNED; - assign decode.r_add_lo = long_mul ? rn : short_rd; + assign decode.r_add_lo = rn; assign decode.r_add_hi = short_rd; assign long_mul = insn `FIELD_MUL_LONG; diff --git a/rtl/core/decode/mux.sv b/rtl/core/decode/mux.sv index fcbe62c..e68729d 100644 --- a/rtl/core/decode/mux.sv +++ b/rtl/core/decode/mux.sv @@ -210,6 +210,9 @@ module core_decode_mux endcase unique casez(insn `FIELD_OP) + // Codificación coincide con ldst + `GROUP_MUL: ; + `GROUP_LDST_SINGLE, `GROUP_LDST_MISC, `GROUP_LDST_MULT: begin ldst = 1; data_ctrl = data_ldst; diff --git a/rtl/core/mul.sv b/rtl/core/mul.sv index 616905f..a801851 100644 --- a/rtl/core/mul.sv +++ b/rtl/core/mul.sv @@ -23,7 +23,7 @@ module core_mul logic wait_state; dword c, q; - assign ready = wait_state == {$bits(wait_state){1'b0}}; + assign ready = !start && wait_state == {$bits(wait_state){1'b0}}; assign {q_hi, q_lo} = q; assign n = long_mul ? q_hi[$bits(q_hi) - 1] : q_lo[$bits(q_lo) - 1]; assign z = q_lo == 0 && (!long_mul || q_hi == 0); @@ -31,7 +31,7 @@ module core_mul dsp_mul ip ( .clock0(clk), - .aclr0(0), //TODO + .aclr0(1), //TODO .ena0(start || !ready), .dataa_0(a), .datab_0(b), diff --git a/rtl/core/uarch.sv b/rtl/core/uarch.sv index a1ca2b1..2b3c55a 100644 --- a/rtl/core/uarch.sv +++ b/rtl/core/uarch.sv @@ -176,7 +176,9 @@ typedef enum TRANSFER, BASE_WRITEBACK, EXCEPTION, - MUL + MUL, + MUL_ACC_LD, + MUL_HI_WB } ctrl_cycle; typedef struct packed |
