[6] | 1 | module l1ddir( |
---|
| 2 | input clk, |
---|
| 3 | input reset, |
---|
| 4 | |
---|
| 5 | input [ 6:0] index, |
---|
| 6 | input [ 1:0] way, |
---|
| 7 | input [28:0] tag, |
---|
| 8 | input strobe, |
---|
| 9 | input query, |
---|
| 10 | input allocate, //tag->{way,index} |
---|
| 11 | input deallocate, //if({way,index}==tag) {way,index}<-FFFFFF |
---|
| 12 | input dualdealloc, |
---|
| 13 | input invalidate, //all ways |
---|
| 14 | |
---|
| 15 | output reg [2:0] hit0, |
---|
| 16 | output reg [2:0] hit1, |
---|
| 17 | |
---|
| 18 | output reg ready // directory init completed |
---|
| 19 | ); |
---|
| 20 | |
---|
| 21 | `define INVAL_TAG 29'h10000000 |
---|
| 22 | |
---|
| 23 | reg [28:0] tag_d; |
---|
| 24 | reg [ 6:0] addr0; |
---|
| 25 | reg [ 5:0] addr1; |
---|
| 26 | reg [ 3:0] we0; |
---|
| 27 | reg [ 3:0] we1; |
---|
| 28 | reg [ 3:0] re; |
---|
| 29 | reg [28:0] di; |
---|
| 30 | reg dualdealloc_d; |
---|
| 31 | wire [28:0] do0_0; |
---|
| 32 | wire [28:0] do1_0; |
---|
| 33 | wire [28:0] do2_0; |
---|
| 34 | wire [28:0] do3_0; |
---|
| 35 | wire [28:0] do0_1; |
---|
| 36 | wire [28:0] do1_1; |
---|
| 37 | wire [28:0] do2_1; |
---|
| 38 | wire [28:0] do3_1; |
---|
| 39 | reg query_d; |
---|
| 40 | reg deallocate_d; |
---|
| 41 | reg query_d1; |
---|
| 42 | reg deallocate_d1; |
---|
| 43 | |
---|
| 44 | always @(posedge clk) |
---|
| 45 | if(strobe) |
---|
| 46 | if(query || deallocate) |
---|
| 47 | begin |
---|
| 48 | tag_d<=tag; |
---|
| 49 | dualdealloc_d<=dualdealloc; |
---|
| 50 | end |
---|
| 51 | |
---|
| 52 | always @(posedge clk) |
---|
| 53 | begin |
---|
| 54 | query_d<=query && strobe; |
---|
| 55 | deallocate_d<=deallocate && strobe; |
---|
| 56 | query_d1<=query_d; |
---|
| 57 | deallocate_d1<=deallocate_d; |
---|
| 58 | end |
---|
| 59 | |
---|
| 60 | cachedir dcache0 ( |
---|
| 61 | .clock(clk), |
---|
| 62 | .enable(we0[0] || we1[0] || re[0]), |
---|
| 63 | .wren_a(we0[0]), |
---|
| 64 | .address_a({1'b0,addr0}), |
---|
| 65 | .data_a(di), |
---|
| 66 | .q_a(do0_0), |
---|
| 67 | |
---|
| 68 | .wren_b(we1[0]), |
---|
| 69 | .address_b({1'b0,addr1,1'b1}), |
---|
| 70 | .data_b(`INVAL_TAG), |
---|
| 71 | .q_b(do0_1) |
---|
| 72 | ); |
---|
| 73 | |
---|
| 74 | cachedir dcache1 ( |
---|
| 75 | .clock(clk), |
---|
| 76 | .enable(we0[1] || we1[1] || re[1]), |
---|
| 77 | .wren_a(we0[1]), |
---|
| 78 | .address_a({1'b0,addr0}), |
---|
| 79 | .data_a(di), |
---|
| 80 | .q_a(do1_0), |
---|
| 81 | |
---|
| 82 | .wren_b(we1[1]), |
---|
| 83 | .address_b({1'b0,addr1,1'b1}), |
---|
| 84 | .data_b(`INVAL_TAG), |
---|
| 85 | .q_b(do1_1) |
---|
| 86 | ); |
---|
| 87 | |
---|
| 88 | cachedir dcache2 ( |
---|
| 89 | .clock(clk), |
---|
| 90 | .enable(we0[2] || we1[2] || re[2]), |
---|
| 91 | .wren_a(we0[2]), |
---|
| 92 | .address_a({1'b0,addr0}), |
---|
| 93 | .data_a(di), |
---|
| 94 | .q_a(do2_0), |
---|
| 95 | |
---|
| 96 | .wren_b(we1[2]), |
---|
| 97 | .address_b({1'b0,addr1,1'b1}), |
---|
| 98 | .data_b(`INVAL_TAG), |
---|
| 99 | .q_b(do2_1) |
---|
| 100 | ); |
---|
| 101 | |
---|
| 102 | cachedir dcache3 ( |
---|
| 103 | .clock(clk), |
---|
| 104 | .enable(we0[3] || we1[3] || re[3]), |
---|
| 105 | .wren_a(we0[3]), |
---|
| 106 | .address_a({1'b0,addr0}), |
---|
| 107 | .data_a(di), |
---|
| 108 | .q_a(do3_0), |
---|
| 109 | |
---|
| 110 | .wren_b(we1[3]), |
---|
| 111 | .address_b({1'b0,addr1,1'b1}), |
---|
| 112 | .data_b(`INVAL_TAG), |
---|
| 113 | .q_b(do3_1) |
---|
| 114 | ); |
---|
| 115 | |
---|
| 116 | wire [3:0] hitvect0={(do3_0==tag_d),(do2_0==tag_d),(do1_0==tag_d),(do0_0==tag_d)}; |
---|
| 117 | wire [3:0] hitvect1={(do3_1==tag_d),(do2_1==tag_d),(do1_1==tag_d),(do0_1==tag_d)}; |
---|
| 118 | |
---|
| 119 | `define L1DDIR_RESET 3'b000 |
---|
| 120 | `define L1DDIR_INIT 3'b001 |
---|
| 121 | `define L1DDIR_IDLE 3'b010 |
---|
| 122 | `define L1DDIR_READ 3'b011 |
---|
| 123 | `define L1DDIR_DEALLOC 3'b100 |
---|
| 124 | |
---|
| 125 | reg [2:0] state; |
---|
| 126 | |
---|
| 127 | always @(posedge clk or posedge reset) |
---|
| 128 | if(reset) |
---|
| 129 | begin |
---|
| 130 | state<=`L1DDIR_RESET; |
---|
| 131 | ready<=0; |
---|
| 132 | end |
---|
| 133 | else |
---|
| 134 | case(state) |
---|
| 135 | `L1DDIR_RESET: |
---|
| 136 | begin |
---|
| 137 | addr0<=7'b0; |
---|
| 138 | addr1<=6'b0; |
---|
| 139 | di<=`INVAL_TAG; |
---|
| 140 | we0<=4'b1111; |
---|
| 141 | we1<=4'b1111; |
---|
| 142 | state<=`L1DDIR_INIT; |
---|
| 143 | end |
---|
| 144 | `L1DDIR_INIT: |
---|
| 145 | begin |
---|
| 146 | addr0<=addr0+2; |
---|
| 147 | addr1<=addr1+1; |
---|
| 148 | if(addr0==7'b1111110) |
---|
| 149 | begin |
---|
| 150 | we0<=4'b0; |
---|
| 151 | we1<=4'b0; |
---|
| 152 | ready<=1; |
---|
| 153 | state<=`L1DDIR_IDLE; |
---|
| 154 | end |
---|
| 155 | end |
---|
| 156 | `L1DDIR_IDLE: |
---|
| 157 | if(strobe) |
---|
| 158 | if(invalidate) |
---|
| 159 | begin |
---|
| 160 | we0<=4'b1111; |
---|
| 161 | we1<=0; |
---|
| 162 | addr0<=index; |
---|
| 163 | di<=`INVAL_TAG; |
---|
| 164 | end |
---|
| 165 | else |
---|
| 166 | if(allocate) |
---|
| 167 | begin |
---|
| 168 | case(way) |
---|
| 169 | 2'b00:we0<=4'b0001; |
---|
| 170 | 2'b01:we0<=4'b0010; |
---|
| 171 | 2'b10:we0<=4'b0100; |
---|
| 172 | 2'b11:we0<=4'b1000; |
---|
| 173 | endcase |
---|
| 174 | we1<=0; |
---|
| 175 | addr0<=index; |
---|
| 176 | di<=tag; |
---|
| 177 | end |
---|
| 178 | else |
---|
| 179 | if(deallocate) |
---|
| 180 | begin |
---|
| 181 | re<=4'b1111; |
---|
| 182 | we0<=0; |
---|
| 183 | we1<=0; |
---|
| 184 | if(dualdealloc) |
---|
| 185 | begin |
---|
| 186 | addr0<={index[6:1],1'b0}; |
---|
| 187 | addr1<=index[6:1]; |
---|
| 188 | end |
---|
| 189 | else |
---|
| 190 | addr0<=index; |
---|
| 191 | state<=`L1DDIR_READ; |
---|
| 192 | end |
---|
| 193 | else |
---|
| 194 | if(query) |
---|
| 195 | begin |
---|
| 196 | addr0<=index; |
---|
| 197 | re<=4'b1111; |
---|
| 198 | we0<=0; |
---|
| 199 | we1<=0; |
---|
| 200 | end |
---|
| 201 | else |
---|
| 202 | begin |
---|
| 203 | we0<=0; |
---|
| 204 | we1<=0; |
---|
| 205 | re<=0; |
---|
| 206 | end |
---|
| 207 | `L1DDIR_READ: |
---|
| 208 | state<=`L1DDIR_DEALLOC; |
---|
| 209 | `L1DDIR_DEALLOC: |
---|
| 210 | begin |
---|
| 211 | re<=0; |
---|
| 212 | di<=`INVAL_TAG; |
---|
| 213 | we0<=hitvect0; |
---|
| 214 | if(dualdealloc_d) |
---|
| 215 | we1<=hitvect1; |
---|
| 216 | else |
---|
| 217 | we1<=0; |
---|
| 218 | state<=`L1DDIR_IDLE; |
---|
| 219 | end |
---|
| 220 | endcase |
---|
| 221 | |
---|
| 222 | always @(posedge clk) |
---|
| 223 | if(query_d1 || deallocate_d1) |
---|
| 224 | begin |
---|
| 225 | case(hitvect0) |
---|
| 226 | 4'b0001:hit0<=3'b100; |
---|
| 227 | 4'b0010:hit0<=3'b101; |
---|
| 228 | 4'b0100:hit0<=3'b110; |
---|
| 229 | 4'b1000:hit0<=3'b111; |
---|
| 230 | default:hit0<=3'b000; // Hits will be ORed then |
---|
| 231 | endcase |
---|
| 232 | if(dualdealloc_d && deallocate_d1) |
---|
| 233 | case(hitvect1) |
---|
| 234 | 4'b0001:hit1<=3'b100; |
---|
| 235 | 4'b0010:hit1<=3'b101; |
---|
| 236 | 4'b0100:hit1<=3'b110; |
---|
| 237 | 4'b1000:hit1<=3'b111; |
---|
| 238 | default:hit1<=3'b000; |
---|
| 239 | endcase |
---|
| 240 | else |
---|
| 241 | hit1<=3'b000; |
---|
| 242 | end |
---|
| 243 | else |
---|
| 244 | if(strobe) |
---|
| 245 | begin |
---|
| 246 | hit0<=3'b000; |
---|
| 247 | hit1<=3'b000; |
---|
| 248 | end |
---|
| 249 | |
---|
| 250 | endmodule |
---|