Commit ea69b7e8591c615cda59a99247864bd1667f5b09
1 parent
1329579e04
Exists in
origin/baseline_v2.3
Added support for LL/SC instructions
Showing 8 changed files with 152 additions and 17 deletions Side-by-side Diff
mips_cpu/mips_core/alu.sv
View file @
ea69b7e
... | ... | @@ -17,18 +17,25 @@ |
17 | 17 | mips_core_pkg::AluCtl alu_ctl; |
18 | 18 | logic signed [`DATA_WIDTH - 1 : 0] op1; |
19 | 19 | logic signed [`DATA_WIDTH - 1 : 0] op2; |
20 | + logic is_ll; | |
21 | + logic is_sc; | |
22 | + logic is_sw; | |
20 | 23 | |
21 | - modport in (input valid, alu_ctl, op1, op2); | |
22 | - modport out (output valid, alu_ctl, op1, op2); | |
24 | + modport in (input valid, alu_ctl, op1, op2, is_ll, is_sc, is_sw); | |
25 | + modport out (output valid, alu_ctl, op1, op2, is_ll, is_sc, is_sw); | |
23 | 26 | endinterface |
24 | 27 | |
25 | 28 | interface alu_output_ifc (); |
26 | 29 | logic valid; |
27 | 30 | logic [`DATA_WIDTH - 1 : 0] result; |
28 | 31 | mips_core_pkg::BranchOutcome branch_outcome; |
32 | + logic is_ll; | |
33 | + logic is_sc; | |
34 | + logic is_sw; | |
29 | 35 | |
30 | - modport in (input valid, result, branch_outcome); | |
31 | - modport out (output valid, result, branch_outcome); | |
36 | + | |
37 | + modport in (input valid, result, branch_outcome, is_ll, is_sc, is_sw); | |
38 | + modport out (output valid, result, branch_outcome, is_ll, is_sc, is_sw); | |
32 | 39 | endinterface |
33 | 40 | |
34 | 41 | module alu ( |
35 | 42 | |
... | ... | @@ -42,13 +49,21 @@ |
42 | 49 | out.valid <= 1'b0; |
43 | 50 | out.result <= '0; |
44 | 51 | out.branch_outcome <= NOT_TAKEN; |
52 | + | |
53 | + out.is_ll <= 1'b0; | |
54 | + out.is_sc <= 1'b0; | |
55 | + out.is_sw <= 1'b0; | |
56 | + | |
45 | 57 | pass_done.value <= '0; |
46 | 58 | pass_done.code <= MTC0_NOOP; |
47 | 59 | |
48 | 60 | if (in.valid) |
49 | 61 | begin |
50 | 62 | out.valid <= 1'b1; |
51 | - | |
63 | + out.is_ll <= in.is_ll; | |
64 | + out.is_sc <= in.is_sc; | |
65 | + out.is_sw <= in.is_sw; | |
66 | + | |
52 | 67 | case (in.alu_ctl) |
53 | 68 | ALUCTL_NOP: out.result <= '0; |
54 | 69 | ALUCTL_ADD: out.result <= in.op1 + in.op2; |
mips_cpu/mips_core/d_cache.sv
View file @
ea69b7e
... | ... | @@ -30,6 +30,7 @@ |
30 | 30 | logic [`ADDR_WIDTH - 1 : 0] addr; |
31 | 31 | logic [`ADDR_WIDTH - 1 : 0] addr_next; |
32 | 32 | logic [`DATA_WIDTH - 1 : 0] data; |
33 | + | |
33 | 34 | |
34 | 35 | modport in (input valid, mem_action, addr, addr_next, data); |
35 | 36 | modport out (output valid, mem_action, addr, addr_next, data); |
... | ... | @@ -42,6 +43,9 @@ |
42 | 43 | // General signals |
43 | 44 | input clk, // Clock |
44 | 45 | input rst_n, // Asynchronous reset active low |
46 | + | |
47 | + //Input from LLSC module | |
48 | + llsc_output_ifc.in llsc_mem_in, | |
45 | 49 | |
46 | 50 | // Request |
47 | 51 | d_cache_input_ifc.in in, |
... | ... | @@ -201,7 +205,7 @@ |
201 | 205 | databank_we <= '0; |
202 | 206 | if (mem_read.user_available) // We are refilling data |
203 | 207 | databank_we <= databank_select; |
204 | - else if (hit & (in.mem_action == WRITE)) // We are storing a word | |
208 | + else if (hit & (in.mem_action == WRITE) && (llsc_mem_in.atomic != ATOMIC_FAIL)) // We are storing a word | |
205 | 209 | databank_we[i_block_offset] <= 1'b1; |
206 | 210 | end |
207 | 211 | |
... | ... | @@ -238,7 +242,7 @@ |
238 | 242 | always_comb |
239 | 243 | begin |
240 | 244 | out.valid = hit; |
241 | - out.data = databank_rdata[i_block_offset]; | |
245 | + out.data = (llsc_mem_in.atomic == ATOMIC_PASS) ? 32'b1 : (llsc_mem_in.atomic == ATOMIC_FAIL) ? 32'b0 : databank_rdata[i_block_offset]; | |
242 | 246 | end |
243 | 247 | |
244 | 248 | always_comb |
mips_cpu/mips_core/decoder.sv
View file @
ea69b7e
... | ... | @@ -33,13 +33,17 @@ |
33 | 33 | |
34 | 34 | logic uses_rw; |
35 | 35 | mips_core_pkg::MipsReg rw_addr; |
36 | + | |
37 | + logic is_ll; | |
38 | + logic is_sc; | |
39 | + logic is_sw; | |
36 | 40 | |
37 | 41 | modport in (input valid, alu_ctl, is_branch_jump, is_jump, is_jump_reg, |
38 | 42 | branch_target, is_mem_access, mem_action, uses_rs, rs_addr, uses_rt, |
39 | - rt_addr, uses_immediate, immediate, uses_rw, rw_addr); | |
43 | + rt_addr, uses_immediate, immediate, uses_rw, rw_addr, is_ll, is_sc, is_sw); | |
40 | 44 | modport out (output valid, alu_ctl, is_branch_jump, is_jump, is_jump_reg, |
41 | 45 | branch_target, is_mem_access, mem_action, uses_rs, rs_addr, uses_rt, |
42 | - rt_addr, uses_immediate, immediate, uses_rw, rw_addr); | |
46 | + rt_addr, uses_immediate, immediate, uses_rw, rw_addr, is_ll, is_sc, is_sw); | |
43 | 47 | endinterface |
44 | 48 | |
45 | 49 | module decoder ( |
... | ... | @@ -168,7 +172,11 @@ |
168 | 172 | |
169 | 173 | out.uses_rw <= 1'b0; |
170 | 174 | out.rw_addr <= zero; |
171 | - | |
175 | + | |
176 | + out.is_ll <= 1'b0; | |
177 | + out.is_sc <= 1'b0; | |
178 | + out.is_sw <= 1'b0; | |
179 | + | |
172 | 180 | if (i_inst.valid) |
173 | 181 | begin |
174 | 182 | case(i_inst.data[31:26]) |
175 | 183 | |
... | ... | @@ -486,10 +494,29 @@ |
486 | 494 | begin |
487 | 495 | out.alu_ctl <= ALUCTL_ADD; |
488 | 496 | out.is_mem_access <= 1'b1; |
497 | + out.is_sw <= 1'b1; | |
489 | 498 | out.mem_action <= WRITE; |
490 | 499 | uses_rs(); |
491 | 500 | uses_rt(); |
492 | 501 | uses_immediate_signed_extend(); |
502 | + end | |
503 | + | |
504 | + 6'h30: //ll | |
505 | + begin | |
506 | + out.alu_ctl <= ALUCTL_ADD; | |
507 | + out.is_mem_access <= 1'b1; | |
508 | + out.is_ll <= 1'b1; | |
509 | + out.mem_action <= READ; | |
510 | + signed_extend_itype(); | |
511 | + end | |
512 | + | |
513 | + 6'h38: //sc | |
514 | + begin | |
515 | + out.alu_ctl <= ALUCTL_ADD; | |
516 | + out.is_mem_access <= 1'b1; | |
517 | + out.is_sc <= 1'b1; | |
518 | + out.mem_action <= WRITE; | |
519 | + signed_extend_itype(); | |
493 | 520 | end |
494 | 521 | |
495 | 522 | 6'h10: //mtc0 |
mips_cpu/mips_core/glue_circuits.sv
View file @
ea69b7e
... | ... | @@ -26,8 +26,12 @@ |
26 | 26 | o_alu_input.alu_ctl = i_decoded.alu_ctl; |
27 | 27 | o_alu_input.op1 = i_reg_data.rs_data; |
28 | 28 | o_alu_input.op2 = i_decoded.uses_immediate |
29 | - ? i_decoded.immediate | |
30 | - : i_reg_data.rt_data; | |
29 | + ? i_decoded.immediate | |
30 | + : i_reg_data.rt_data; | |
31 | + o_alu_input.is_ll = i_decoded.is_ll; | |
32 | + o_alu_input.is_sc = i_decoded.is_sc; | |
33 | + o_alu_input.is_sw = i_decoded.is_sw; | |
34 | + | |
31 | 35 | |
32 | 36 | branch_decoded.valid = i_decoded.is_branch_jump; |
33 | 37 | branch_decoded.is_jump = i_decoded.is_jump; |
... | ... | @@ -53,7 +57,8 @@ |
53 | 57 | module ex_stage_glue ( |
54 | 58 | alu_output_ifc.in i_alu_output, |
55 | 59 | alu_pass_through_ifc.in i_alu_pass_through, |
56 | - | |
60 | + | |
61 | + llsc_input_ifc.out o_llsc_input, | |
57 | 62 | branch_result_ifc.out o_branch_result, |
58 | 63 | d_cache_input_ifc.out o_d_cache_input, |
59 | 64 | d_cache_pass_through_ifc.out o_d_cache_pass_through |
... | ... | @@ -61,6 +66,11 @@ |
61 | 66 | |
62 | 67 | always_comb |
63 | 68 | begin |
69 | + o_llsc_input.is_sw = i_alu_output.is_sw; | |
70 | + o_llsc_input.lladdr_wr = i_alu_output.is_ll; | |
71 | + o_llsc_input.is_sc = i_alu_output.is_sc; | |
72 | + o_llsc_input.wr_reg_val = {6'b0,i_alu_output.result[`ADDR_WIDTH - 1 : 0]}; | |
73 | + | |
64 | 74 | o_branch_result.valid = i_alu_output.valid |
65 | 75 | & i_alu_pass_through.is_branch; |
66 | 76 | o_branch_result.prediction = i_alu_pass_through.prediction; |
... | ... | @@ -83,7 +93,7 @@ |
83 | 93 | module mem_stage_glue ( |
84 | 94 | cache_output_ifc.in i_d_cache_output, |
85 | 95 | d_cache_pass_through_ifc.in i_d_cache_pass_through, |
86 | - | |
96 | + | |
87 | 97 | output logic o_done, |
88 | 98 | write_back_ifc.out o_write_back |
89 | 99 | ); |
mips_cpu/mips_core/llsc_module.sv
View file @
ea69b7e
1 | +/* | |
2 | + * lladdr.sv | |
3 | + * Author: Sumiran Shubhi | |
4 | + * Last Revision: 04/03/2020 | |
5 | + * | |
6 | + * Module to store current LLADDR register value for processing LL and SC | |
7 | + * instructions. | |
8 | + */ | |
9 | + `include "mips_core.svh" | |
10 | + | |
11 | + interface llsc_input_ifc(); | |
12 | + logic is_sw; | |
13 | + logic lladdr_wr; | |
14 | + logic [`DATA_WIDTH - 1 : 0] wr_reg_val; | |
15 | + logic is_sc; | |
16 | + | |
17 | + modport in (input wr_reg_val, lladdr_wr, is_sw, is_sc); | |
18 | + modport out (output wr_reg_val, lladdr_wr, is_sw, is_sc); | |
19 | + endinterface | |
20 | + | |
21 | + interface llsc_output_ifc(); | |
22 | + mips_core_pkg::AtomicStatus atomic; | |
23 | + | |
24 | + modport in (input atomic); | |
25 | + modport out (output atomic); | |
26 | + endinterface | |
27 | + | |
28 | + module llsc_module ( | |
29 | + input clk, // Clock | |
30 | + // Input from ALU stage | |
31 | + llsc_input_ifc.in i_llsc, | |
32 | + | |
33 | + // Output to MEM stage | |
34 | + llsc_output_ifc.out o_llsc | |
35 | +); | |
36 | + logic [`DATA_WIDTH - 1 : 0] LLAddr; | |
37 | + logic LLbit; | |
38 | + | |
39 | + always_comb begin | |
40 | + o_llsc.atomic = (LLbit && i_llsc.is_sc && (LLAddr==i_llsc.wr_reg_val)) ? ATOMIC_PASS | |
41 | + : (LLbit && i_llsc.is_sc && (LLAddr!= i_llsc.wr_reg_val)) ? ATOMIC_FAIL | |
42 | + : NOT_ATOMIC ; | |
43 | + end | |
44 | + | |
45 | + always_ff @(posedge clk) begin | |
46 | + if (i_llsc.is_sw && LLbit && (LLAddr==i_llsc.wr_reg_val)) begin | |
47 | + LLAddr <= 0; | |
48 | + LLbit <= 0; | |
49 | + end | |
50 | + else if(i_llsc.lladdr_wr) begin | |
51 | + LLAddr <= i_llsc.wr_reg_val; | |
52 | + LLbit <= 1; | |
53 | + end | |
54 | + | |
55 | + end | |
56 | +endmodule |
mips_cpu/mips_core/mips_core.sv
View file @
ea69b7e
... | ... | @@ -50,12 +50,14 @@ |
50 | 50 | |
51 | 51 | // |||| EX Stage |
52 | 52 | alu_output_ifc ex_alu_output(); |
53 | + llsc_input_ifc ex_llsc_input(); | |
53 | 54 | branch_result_ifc ex_branch_result(); |
54 | 55 | d_cache_input_ifc ex_d_cache_input(); |
55 | 56 | d_cache_pass_through_ifc ex_d_cache_pass_through(); |
56 | 57 | |
57 | 58 | // ==== EX to MEM |
58 | 59 | pc_ifc e2m_pc(); |
60 | + llsc_output_ifc llsc_mem_output(); | |
59 | 61 | d_cache_input_ifc e2m_d_cache_input(); |
60 | 62 | d_cache_pass_through_ifc e2m_d_cache_pass_through(); |
61 | 63 | |
62 | 64 | |
63 | 65 | |
... | ... | @@ -182,11 +184,18 @@ |
182 | 184 | .out(ex_alu_output), |
183 | 185 | .pass_done |
184 | 186 | ); |
187 | + | |
188 | + llsc_module LLSC_mod( | |
189 | + .clk(clk), | |
190 | + .i_llsc(ex_llsc_input), | |
191 | + .o_llsc(llsc_mem_output) | |
192 | +); | |
185 | 193 | |
194 | + | |
186 | 195 | ex_stage_glue EX_STAGE_GLUE ( |
187 | 196 | .i_alu_output (ex_alu_output), |
188 | 197 | .i_alu_pass_through (d2e_alu_pass_through), |
189 | - | |
198 | + .o_llsc_input (ex_llsc_input), | |
190 | 199 | .o_branch_result (ex_branch_result), |
191 | 200 | .o_d_cache_input (ex_d_cache_input), |
192 | 201 | .o_d_cache_pass_through (ex_d_cache_pass_through) |
... | ... | @@ -215,7 +224,7 @@ |
215 | 224 | |
216 | 225 | .in(e2m_d_cache_input), |
217 | 226 | .out(mem_d_cache_output), |
218 | - | |
227 | + .llsc_mem_in(llsc_mem_output), | |
219 | 228 | .mem_read(d_cache_read), |
220 | 229 | .mem_write(d_cache_write) |
221 | 230 | ); |
mips_cpu/mips_core/mips_core_pkg.sv
View file @
ea69b7e
mips_cpu/mips_core/pipeline_registers.sv
View file @
ea69b7e
... | ... | @@ -81,6 +81,9 @@ |
81 | 81 | o_alu_input.alu_ctl <= ALUCTL_NOP; |
82 | 82 | o_alu_input.op1 <= '0; |
83 | 83 | o_alu_input.op2 <= '0; |
84 | + o_alu_input.is_ll <= '0; | |
85 | + o_alu_input.is_sc <= '0; | |
86 | + o_alu_input.is_sw <= '0; | |
84 | 87 | |
85 | 88 | |
86 | 89 | o_alu_pass_through.is_branch <= 1'b0; |
... | ... | @@ -107,6 +110,9 @@ |
107 | 110 | o_alu_input.alu_ctl <= ALUCTL_NOP; |
108 | 111 | o_alu_input.op1 <= '0; |
109 | 112 | o_alu_input.op2 <= '0; |
113 | + o_alu_input.is_ll <= '0; | |
114 | + o_alu_input.is_sc <= '0; | |
115 | + o_alu_input.is_sw <= '0; | |
110 | 116 | |
111 | 117 | |
112 | 118 | o_alu_pass_through.is_branch <= 1'b0; |
... | ... | @@ -129,7 +135,9 @@ |
129 | 135 | o_alu_input.alu_ctl <= i_alu_input.alu_ctl; |
130 | 136 | o_alu_input.op1 <= i_alu_input.op1; |
131 | 137 | o_alu_input.op2 <= i_alu_input.op2; |
132 | - | |
138 | + o_alu_input.is_ll <= i_alu_input.is_ll; | |
139 | + o_alu_input.is_sc <= i_alu_input.is_sc; | |
140 | + o_alu_input.is_sw <= i_alu_input.is_sw; | |
133 | 141 | |
134 | 142 | o_alu_pass_through.is_branch <= i_alu_pass_through.is_branch; |
135 | 143 | o_alu_pass_through.prediction <= i_alu_pass_through.prediction; |