1 /******************************************************************************
  2 * Copyright 2013, Hectic Tech (Jeff Heckey). All rights reserved
  3 ******************************************************************************/
  4 
  5 module regfile #(
  6     parameter OP = 3,
  7     parameter TAG = 4,
  8     parameter ADDR = 32,
  9     parameter DATA = 32
 10 ) (
 11     input  wire                     clk,
 12     input  wire                     rstn,
 13 
 14     input  wire [TAG-1:0]           cdb_a_id,
 15     input  wire [DATA-1:0]          cdb_a_data,
 16     input  wire [TAG-1:0]           cdb_m_id,
 17     input  wire [DATA-1:0]          cdb_m_data,
 18     input  wire [TAG-1:0]           cdb_l_id,
 19     input  wire [DATA-1:0]          cdb_l_data,
 20     input  wire [OP+4*TAG-1:0]      disp_bus0,
 21     input  wire [OP+4*TAG-1:0]      disp_bus1,
 22 
 23     input  wire                     cf_val,
 24     input  wire [TAG-1:0]           cf_addr,
 25     input  wire [DATA-1:0]          cf_data,
 26 
 27     output reg  [TAG-1:0]           cdb_r0_id,
 28     output reg  [DATA-1:0]          cdb_r0_data,
 29     output reg  [TAG-1:0]           cdb_r1_id,
 30     output reg  [DATA-1:0]          cdb_r1_data,
 31     output reg  [TAG-1:0]           cdb_r2_id,
 32     output reg  [DATA-1:0]          cdb_r2_data
 33 );
 34 
 35 localparam R0 = 4'd4,
 36            R1 = 4'd5,
 37            R2 = 4'd6,
 38            R3 = 4'd7,
 39            A0 = 4'd8,
 40            A1 = 4'd9,
 41            M0 = 4'd10,
 42            M1 = 4'd11,
 43            L0 = 4'd12,
 44            L1 = 4'd13,
 45            S0 = 4'd14,
 46            S1 = 4'd15;
 47 
 48 reg [TAG-1:0]           cdb_a_idN;
 49 reg [DATA-1:0]          cdb_a_dataN;
 50 reg [TAG-1:0]           cdb_m_idN;
 51 reg [DATA-1:0]          cdb_m_dataN;
 52 reg [TAG-1:0]           cdb_l_idN;
 53 reg [DATA-1:0]          cdb_l_dataN;
 54 reg [OP+4*TAG+ADDR-1:0] disp_bus0N;
 55 reg [OP+4*TAG+ADDR-1:0] disp_bus1N;
 56 
 57 reg                      cf_valN;
 58 reg  [TAG:0]             cf_addrN;
 59 reg  [DATA-1:0]          cf_dataN;
 60 
 61 integer i, neg, pos;
 62 
 63 reg [3:0]       pending, pending_nextN, pendingN;
 64 reg [TAG-1:0]   tagfile[3:0], tagfile_nextN[3:0], tagfileN[3:0];
 65 reg [DATA-1:0]  regfile[3:0], regfile_nextN[3:0], regfileN[3:0];
 66 reg [OP-1:0]    op0N, op1N;
 67 reg [TAG-1:0]   rsv0N, rsv1N;
 68 reg [TAG-1:0]   dst0N, dst1N;
 69 reg [TAG-1:0]   src01N, src02N;
 70 reg [TAG-1:0]   src11N, src12N;
 71 
 72 
 73 always @* begin : RF_NEG_LATCHES
 74     if ( !rstn ) begin
 75         cdb_a_idN   <= {TAG{1'b0}};
 76         cdb_a_dataN <= {DATA{1'b0}};
 77         cdb_m_idN   <= {TAG{1'b0}};
 78         cdb_m_dataN <= {DATA{1'b0}};
 79         cdb_l_idN   <= {TAG{1'b0}};
 80         cdb_l_dataN <= {DATA{1'b0}};
 81         disp_bus0N  <= {OP+4*TAG{1'b0}};
 82         disp_bus1N  <= {OP+4*TAG{1'b0}};
 83 
 84         cf_valN     <= 1'b0;
 85         cf_addrN    <= {TAG{1'b0}};
 86         cf_dataN    <= {DATA{1'b0}};
 87 
 88         pendingN    <= pending;
 89         for ( neg=0; neg<4; neg=neg+1 ) begin
 90             tagfileN[neg] <= {TAG{1'b0}};
 91             regfileN[neg] <= {DATA{1'b0}};
 92         end
 93     end
 94     else begin
 95         if ( !clk ) begin
 96             cdb_a_idN   <= cdb_a_id;
 97             cdb_a_dataN <= cdb_a_data;
 98             cdb_m_idN   <= cdb_m_id;
 99             cdb_m_dataN <= cdb_m_data;
100             cdb_l_idN   <= cdb_l_id;
101             cdb_l_dataN <= cdb_l_data;
102             disp_bus0N  <= disp_bus0;
103             disp_bus1N  <= disp_bus1;
104 
105             cf_valN     <= cf_val;
106             cf_addrN    <= cf_addr;
107             cf_dataN    <= cf_data;
108 
109             pendingN    <= pending;
110             for ( neg=0; neg<4; neg=neg+1 ) begin
111                 tagfileN[neg] <= tagfile[neg];
112                 regfileN[neg] <= regfile[neg];
113             end
114         end
115     end
116 end
117 
118 always @* begin : RF_NEG_LOGIC
119     {rsv0N,
120      op0N,
121      dst0N,
122      src01N,
123      src02N} = disp_bus0N;
124     {rsv1N,
125      op1N,
126      dst1N,
127      src11N,
128      src12N} = disp_bus1N;
129 
130     for ( i=0; i<4; i=i+1 ) begin
131         // Resolve data
132         if ( cf_valN && cf_addrN == (R0 + i) ) begin
133             regfile_nextN[i] = cf_dataN;
134         end
135         else if ( |cdb_a_idN && tagfileN[i] == cdb_a_idN ) begin
136             regfile_nextN[i] = cdb_a_dataN;
137         end
138         else if ( |cdb_m_idN && tagfileN[i] == cdb_m_idN ) begin
139             regfile_nextN[i] = cdb_m_dataN;
140         end
141         else if ( |cdb_l_idN && tagfileN[i] == cdb_l_idN ) begin
142             regfile_nextN[i] = cdb_l_dataN;
143         end
144         else begin
145             regfile_nextN[i] = regfileN[i];
146         end
147 
148         // Resolve tags:
149         // -- Check for updates (INST1 has precedence over INST0)
150         // -- Then clear if found
151         // -- Or hold value if nothing has happened
152         if ( cf_valN && cf_addrN == (R0 + i) ) begin
153             tagfile_nextN[i] = {TAG{1'b0}};
154         end
155         else if ( dst1N == R0+i ) begin
156             tagfile_nextN[i] = rsv1N;
157         end
158         else if ( dst0N == R0+i ) begin
159             tagfile_nextN[i] = rsv0N;
160         end
161         else if ( |cdb_a_idN && tagfileN[i] == cdb_a_idN ) begin
162             tagfile_nextN[i] = {TAG{1'b0}};
163         end
164         else if ( |cdb_m_idN && tagfileN[i] == cdb_m_idN ) begin
165             tagfile_nextN[i] = {TAG{1'b0}};
166         end
167         else if ( |cdb_l_idN && tagfileN[i] == cdb_l_idN ) begin
168             tagfile_nextN[i] = {TAG{1'b0}};
169         end
170         else begin
171             tagfile_nextN[i] = tagfileN[i];
172         end
173     end
174 
175     // Figure out requests
176     pending_nextN = pendingN;
177     pending_nextN = ( |rsv0N && src01N[3:2] == 2'b01 ) ? pending_nextN | ( 4'b0001 << src01N[1:0] ) : pending_nextN;
178     pending_nextN = ( |rsv0N && src02N[3:2] == 2'b01 ) ? pending_nextN | ( 4'b0001 << src02N[1:0] ) : pending_nextN;
179     pending_nextN = ( |rsv1N && src11N[3:2] == 2'b01 ) ? pending_nextN | ( 4'b0001 << src11N[1:0] ) : pending_nextN;
180     pending_nextN = ( |rsv1N && src11N[3:2] == 2'b01 ) ? pending_nextN | ( 4'b0001 << src12N[1:0] ) : pending_nextN;
181 
182 end
183 
184 always @* begin : RF_POS_LATCHES
185     if ( !rstn ) begin
186         cdb_r0_id   <= {TAG{1'b0}};
187         cdb_r0_data <= {DATA{1'b0}};
188         cdb_r1_id   <= {TAG{1'b0}};
189         cdb_r1_data <= {DATA{1'b0}};
190         cdb_r2_id   <= {TAG{1'b0}};
191         cdb_r2_data <= {DATA{1'b0}};
192 
193         pending     <= 4'b0000;
194         for ( pos=0; pos<4; pos=pos+1 ) begin
195             tagfile[pos]    <= {TAG{1'b0}};
196             regfile[pos]    <= {DATA{1'b0}};
197         end
198     end
199     else begin
200         if ( clk ) begin
201             for ( pos=0; pos<4; pos=pos+1 ) begin
202                 tagfile[pos]    <= tagfile_nextN[pos];
203                 regfile[pos]    <= regfile_nextN[pos];
204             end
205 
206             case ( pending_nextN )
207             4'd15:
208             begin
209                 cdb_r0_id   <= R0;
210                 cdb_r0_data <= regfileN[0];
211                 cdb_r1_id   <= R1;
212                 cdb_r1_data <= regfileN[1];
213                 cdb_r2_id   <= R2;
214                 cdb_r2_data <= regfileN[2];
215                 pending     <= 4'b1000;
216             end
217 
218             4'd14:
219             begin
220                 cdb_r0_id   <= R1;
221                 cdb_r0_data <= regfileN[1];
222                 cdb_r1_id   <= R2;
223                 cdb_r1_data <= regfileN[2];
224                 cdb_r2_id   <= R3;
225                 cdb_r2_data <= regfileN[3];
226                 pending     <= 4'b0000;
227             end
228 
229             4'd13:
230             begin
231                 cdb_r0_id   <= R0;
232                 cdb_r0_data <= regfileN[0];
233                 cdb_r1_id   <= R2;
234                 cdb_r1_data <= regfileN[2];
235                 cdb_r2_id   <= R3;
236                 cdb_r2_data <= regfileN[3];
237                 pending     <= 4'b0000;
238             end
239 
240             4'd12:
241             begin
242                 cdb_r0_id   <= R2;
243                 cdb_r0_data <= regfileN[1];
244                 cdb_r1_id   <= R3;
245                 cdb_r1_data <= regfileN[2];
246                 cdb_r2_id   <= {TAG{1'b0}};
247                 cdb_r2_data <= {DATA{1'b0}};
248                 pending     <= 4'b0000;
249             end
250 
251             4'd11:
252             begin
253                 cdb_r0_id   <= R0;
254                 cdb_r0_data <= regfileN[0];
255                 cdb_r1_id   <= R1;
256                 cdb_r1_data <= regfileN[1];
257                 cdb_r2_id   <= R3;
258                 cdb_r2_data <= regfileN[3];
259                 pending     <= 4'b0000;
260             end
261 
262             4'd10:
263             begin
264                 cdb_r0_id   <= R1;
265                 cdb_r0_data <= regfileN[1];
266                 cdb_r1_id   <= R3;
267                 cdb_r1_data <= regfileN[3];
268                 cdb_r2_id   <= {TAG{1'b0}};
269                 cdb_r2_data <= {DATA{1'b0}};
270                 pending     <= 4'b0000;
271             end
272 
273             4'd9:
274             begin
275                 cdb_r0_id   <= R0;
276                 cdb_r0_data <= regfileN[0];
277                 cdb_r1_id   <= R3;
278                 cdb_r1_data <= regfileN[3];
279                 cdb_r2_id   <= {TAG{1'b0}};
280                 cdb_r2_data <= {DATA{1'b0}};
281                 pending     <= 4'b0000;
282             end
283 
284             4'd8:
285             begin
286                 cdb_r0_id   <= R3;
287                 cdb_r0_data <= regfileN[3];
288                 cdb_r1_id   <= {TAG{1'b0}};
289                 cdb_r1_data <= {DATA{1'b0}};
290                 cdb_r2_id   <= {TAG{1'b0}};
291                 cdb_r2_data <= {DATA{1'b0}};
292                 pending     <= 4'b0000;
293             end
294 
295             4'd7:
296             begin
297                 cdb_r0_id   <= R0;
298                 cdb_r0_data <= regfileN[0];
299                 cdb_r1_id   <= R1;
300                 cdb_r1_data <= regfileN[1];
301                 cdb_r2_id   <= R2;
302                 cdb_r2_data <= regfileN[2];
303                 pending     <= 4'b0000;
304             end
305 
306             4'd6:
307             begin
308                 cdb_r0_id   <= R1;
309                 cdb_r0_data <= regfileN[1];
310                 cdb_r1_id   <= R2;
311                 cdb_r1_data <= regfileN[2];
312                 cdb_r2_id   <= {TAG{1'b0}};
313                 cdb_r2_data <= {DATA{1'b0}};
314                 pending     <= 4'b0000;
315             end
316 
317             4'd5:
318             begin
319                 cdb_r0_id   <= R0;
320                 cdb_r0_data <= regfileN[0];
321                 cdb_r1_id   <= R2;
322                 cdb_r1_data <= regfileN[2];
323                 cdb_r2_id   <= {TAG{1'b0}};
324                 cdb_r2_data <= {DATA{1'b0}};
325                 pending     <= 4'b0000;
326             end
327 
328             4'd4:
329             begin
330                 cdb_r0_id   <= R2;
331                 cdb_r0_data <= regfileN[2];
332                 cdb_r1_id   <= {TAG{1'b0}};
333                 cdb_r1_data <= {DATA{1'b0}};
334                 cdb_r2_id   <= {TAG{1'b0}};
335                 cdb_r2_data <= {DATA{1'b0}};
336                 pending     <= 4'b0000;
337             end
338 
339             4'd3:
340             begin
341                 cdb_r0_id   <= R0;
342                 cdb_r0_data <= regfileN[0];
343                 cdb_r1_id   <= R1;
344                 cdb_r1_data <= regfileN[1];
345                 cdb_r2_id   <= {TAG{1'b0}};
346                 cdb_r2_data <= {DATA{1'b0}};
347                 pending     <= 4'b0000;
348             end
349 
350             4'd2:
351             begin
352                 cdb_r0_id   <= R1;
353                 cdb_r0_data <= regfileN[1];
354                 cdb_r1_id   <= {TAG{1'b0}};
355                 cdb_r1_data <= {DATA{1'b0}};
356                 cdb_r2_id   <= {TAG{1'b0}};
357                 cdb_r2_data <= {DATA{1'b0}};
358                 pending     <= 4'b0000;
359             end
360 
361             4'd1:
362             begin
363                 cdb_r0_id   <= R0;
364                 cdb_r0_data <= regfileN[0];
365                 cdb_r1_id   <= {TAG{1'b0}};
366                 cdb_r1_data <= {DATA{1'b0}};
367                 cdb_r2_id   <= {TAG{1'b0}};
368                 cdb_r2_data <= {DATA{1'b0}};
369                 pending     <= 4'b0000;
370             end
371 
372             4'd0:
373             begin
374                 cdb_r0_id   <= {TAG{1'b0}};
375                 cdb_r0_data <= {DATA{1'b0}};
376                 cdb_r1_id   <= {TAG{1'b0}};
377                 cdb_r1_data <= {DATA{1'b0}};
378                 cdb_r2_id   <= {TAG{1'b0}};
379                 cdb_r2_data <= {DATA{1'b0}};
380                 pending     <= 4'b0000;
381             end
382             endcase
383         end
384     end
385 end
386 
387 endmodule
388