OpenCores
URL https://opencores.org/ocsvn/oops/oops/trunk

Subversion Repositories oops

[/] [oops/] [trunk/] [rtl/] [map_table.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 smjoshua
//////////////////////////////////////////////////////////////////
2
//                                                              //
3
//  OoOPs Core Register Map Table module                        //
4
//                                                              //
5
//  This file is part of the OoOPs project                      //
6
//  http://www.opencores.org/project,oops                       //
7
//                                                              //
8
//  Description:                                                //
9
//  The Map Table is responsible for maintaining the mapping    //
10
//  from architectural->physical registers.  This block         //
11
//  consists of a free list for allocating new physical         //
12
//  registers and also the tables for mapping source operands.  // 
13
//                                                              //
14
//  To avoid excessive flop usage for the map tables, block rams//
15
//  will be used instead.                                       //
16
//                                                              //
17
//  Author(s):                                                  //
18
//      - Joshua Smith, smjoshua@umich.edu                      //
19
//                                                              //
20
//////////////////////////////////////////////////////////////////
21
//                                                              //
22
// Copyright (C) 2012 Authors and OPENCORES.ORG                 //
23
//                                                              //
24
// This source file may be used and distributed without         //
25
// restriction provided that this copyright statement is not    //
26
// removed from the file and that any derivative work contains  //
27
// the original copyright notice and the associated disclaimer. //
28
//                                                              //
29
// This source file is free software; you can redistribute it   //
30
// and/or modify it under the terms of the GNU Lesser General   //
31
// Public License as published by the Free Software Foundation; //
32
// either version 2.1 of the License, or (at your option) any   //
33
// later version.                                               //
34
//                                                              //
35
// This source is distributed in the hope that it will be       //
36
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
37
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
38
// PURPOSE.  See the GNU Lesser General Public License for more //
39
// details.                                                     //
40
//                                                              //
41
// You should have received a copy of the GNU Lesser General    //
42
// Public License along with this source; if not, download it   //
43
// from http://www.opencores.org/lgpl.shtml                     //
44
//                                                              //
45
//////////////////////////////////////////////////////////////////
46
`include "ooops_defs.v"
47
 
48
module map_table (
49
  input wire                      clk,
50
  input wire                      rst,
51
  output wire                     map_table_init,
52
 
53
  // Rename port
54
  input wire                      ds1_valid,
55
  input wire  [`REG_IDX_SZ-1:0]   ds1_src1_idx,
56
  input wire  [`REG_IDX_SZ-1:0]   ds1_src2_idx,
57
  input wire  [`REG_IDX_SZ-1:0]   ds1_dest_idx,
58
  input wire                      ds1_dest_wr,
59
  input wire                      ds1_type_br,
60
  output wire [`TAG_SZ-1:0]       ds2_src1_tag,
61
  output wire [`TAG_SZ-1:0]       ds2_src2_tag,
62
  output wire                     ds2_src1_valid,
63
  output wire                     ds2_src2_valid,
64
  output wire [`TAG_SZ-1:0]       ds2_dest_tag,
65
  output wire [`TAG_SZ-1:0]       ds2_dest_tag_old,
66
  output wire [`FL_PTR_SZ-1:0]    ds2_fl_head_ptr,
67
  output wire [`CHKPT_PTR_SZ-1:0] ds2_chkpt_ptr,
68
 
69
  // Writeback port
70
  //input wire  [`CDB_BUS_SZ-1:0]   ex_cdb_bus,
71
 
72
  // Retire and flush port
73
  input wire                      rob_pipe_flush,
74
  input wire                      rob_ds_ret_valid,
75
  input wire                      rob_ds_ret_dest_write,
76
  input wire  [`CHKPT_PTR_SZ-1:0] rob_ds_chkpt_ptr,
77
  input wire  [`FL_PTR_SZ-1:0]    rob_ds_fl_head_ptr,
78
  input wire                      rob_ds_ret_chkpt_free,
79
  input wire  [`REG_IDX_SZ-1:0]   rob_ds_ret_idx,
80
  input wire  [`TAG_SZ-1:0]       rob_ds_ret_tag,
81
  input wire  [`TAG_SZ-1:0]       rob_ds_ret_tag_old
82
  );
83
 
84
  // Internal wires and regs
85
  wire  [`TAG_SZ-1:0]       ds1_dest_tag;
86
  wire  [`FL_PTR_SZ-1:0]    ds1_fl_head_ptr;
87
  wire  [`ARCH_REGS-1:0]    dfa_dirty_bit [`CHKPT_NUM-1:0];
88
  wire  [`ARCH_REGS-1:0]    dfa_dirty_bit_in [`CHKPT_NUM-1:0];
89
  wire  [`CHKPT_NUM-1:0]    dfa_dirty_bit_ld; // load is per checkpoint/column
90
  wire  [`CHKPT_NUM-1:0]    dfa_dirty_bit_row [`ARCH_REGS-1:0];
91
  wire  [`CHKPT_PTR_SZ-1:0] ds1_src1_chkpt, ds1_src2_chkpt, ds1_dest_chkpt;
92
 
93
  wire  [`CHKPT_PTR_SZ-1:0] chkpt_head_ptr;
94
  wire  [`CHKPT_PTR_SZ-1:0] chkpt_head_ptr_p1;
95
  wire  [`CHKPT_PTR_SZ-1:0] chkpt_tail_ptr;
96
  wire  [`CHKPT_PTR_SZ-1:0] chkpt_tail_ptr_p1;
97
  wire  [`CHKPT_NUM-1:0]    chkpt_valid_mask;
98
  wire  [`CHKPT_NUM-1:0]    chkpt_valid_mask_in;
99
  wire                      chkpt_allocate;
100
 
101
  genvar                    g,k;
102
 
103
  // Instantiate free list
104
  free_list fl (
105
    .clk(clk),
106
    .rst(rst),
107
    .ds1_dest_wr(ds1_dest_wr),
108
    .rob_pipe_flush(rob_pipe_flush),
109
    .rob_ds_fl_head_ptr(rob_ds_fl_head_ptr),
110
    .rob_ds_ret_valid(rob_ds_ret_valid),
111
    .rob_ds_ret_dest_write(rob_ds_ret_dest_write),
112
    .rob_ds_ret_tag_old(rob_ds_ret_tag_old),
113
    .ds1_dest_tag(ds1_dest_tag),
114
    .ds1_fl_head_ptr(ds1_fl_head_ptr)
115
  );
116
 
117
  // Maintain the checkpoint head/tail pointers
118
  // Operation:
119
  // - Upon a pipe flush, restore both head and tail pointers to same pointer value from the ROB.
120
  // - When a new checkpoint is allocated, advance head pointer by 1
121
  // - When an instruction which allocated a checkpoint retires, advance tail pointer by 1.
122
  assign chkpt_allocate = ds1_type_br & ~rob_pipe_flush;
123
  wire [`CHKPT_PTR_SZ-1:0] chkpt_head_ptr_in = rob_pipe_flush ? rob_ds_chkpt_ptr : chkpt_head_ptr_p1;
124
  wire [`CHKPT_PTR_SZ-1:0] chkpt_tail_ptr_in = rob_pipe_flush ? rob_ds_chkpt_ptr : chkpt_tail_ptr_p1;
125
  wire chkpt_head_ptr_ld = rob_pipe_flush | chkpt_allocate;
126
  wire chkpt_tail_ptr_ld = rob_pipe_flush | (rob_ds_ret_valid & rob_ds_ret_chkpt_free);
127
 
128
  MDFFLR #(`CHKPT_PTR_SZ) chkpt_head_ptr_ff (clk, rst, chkpt_head_ptr_ld, `CHKPT_PTR_SZ'h0, chkpt_head_ptr_in, chkpt_head_ptr);
129
  MDFFLR #(`CHKPT_PTR_SZ) chkpt_tail_ptr_ff (clk, rst, chkpt_tail_ptr_ld, `CHKPT_PTR_SZ'h0, chkpt_tail_ptr_in, chkpt_tail_ptr);
130
 
131
  assign chkpt_head_ptr_p1 = (chkpt_head_ptr == `CHKPT_NUM-1) ? `CHKPT_PTR_SZ'h0 : chkpt_head_ptr + `CHKPT_PTR_SZ'h1;
132
  assign chkpt_tail_ptr_p1 = (chkpt_tail_ptr == `CHKPT_NUM-1) ? `CHKPT_PTR_SZ'h0 : chkpt_tail_ptr + `CHKPT_PTR_SZ'h1;
133
 
134
  // Keep a bit-vector mask of valid (allocated) checkpoints for the DFA search
135
  // Initialize checkpoint 0 to valid, this will be the checkpoint used out of reset.
136
  wire [`CHKPT_NUM-1:0] allocated_chkpt = (`CHKPT_NUM'h1 << chkpt_head_ptr_p1) & {`CHKPT_NUM{chkpt_allocate}};
137
  wire [`CHKPT_NUM-1:0] freed_chkpt     = (`CHKPT_NUM'h1 << chkpt_tail_ptr) & {`CHKPT_NUM{rob_ds_ret_chkpt_free}};
138
  wire [`CHKPT_NUM-1:0] rob_ds_chkpt_vec = (`CHKPT_NUM'h1 << rob_ds_chkpt_ptr);
139
  assign chkpt_valid_mask_in = rob_pipe_flush ? rob_ds_chkpt_vec : ((chkpt_valid_mask | allocated_chkpt) & ~freed_chkpt);
140
  MDFFLR #(`CHKPT_NUM)    chkpt_valid_mask_ff (clk, rst, chkpt_head_ptr_ld | chkpt_tail_ptr_ld, `CHKPT_NUM'h1, chkpt_valid_mask_in, chkpt_valid_mask);
141
 
142
  /*
143
   Handle the DFA (Dirty Flag Array) for determining which checkpoint contains the
144
   most recent mapping for an architectural register.  This is needed to setup the
145
   SRAM address input for the RAT lookup.
146
 
147
   Structure:
148
   - Maintain a grid of bits (one row for each arch. reg, one column for each checkpoint).
149
   - Head/Tail pointer keep track of most recently/least recently allocated valid checkpoints.
150
 
151
   Operation:
152
   - When a new checkpoint is allocated for a branch or speculation point, we advance
153
     the head pointer and clear the entire DFA column for that checkpoint.  For branches which
154
     write a register, the write should update the old checkpoint, not the newly allocated one.
155
   - When a register write operation comes through, update the row of the head checkpoint
156
     corresponding to the destination architectural register index.
157
 
158
  */
159
  wire [`CHKPT_NUM-1:0] dfa_column_clear = allocated_chkpt;
160
  wire [`CHKPT_NUM-1:0] ds1_active_chkpt = (`CHKPT_NUM'h1 << chkpt_head_ptr);
161
  assign dfa_dirty_bit_ld = dfa_column_clear |                                // Clear newly allocated checkpoint
162
                            (ds1_active_chkpt & {`CHKPT_NUM{ds1_dest_wr}});   // Update current checkpoint
163
 
164
  wire [`ARCH_REGS-1:0] ds1_dest_idx_vec = (1 << ds1_dest_idx);
165
  generate
166
    for (g=0; g<`CHKPT_NUM; g=g+1) begin : dfa_gen
167
      for (k=0; k<`ARCH_REGS; k=k+1) begin : dfa_dirty_bit_gen
168
        assign dfa_dirty_bit_in[g][k] = ~dfa_column_clear[g] & ((ds1_dest_idx_vec[k] & ds1_dest_wr) ? 1'b1 : dfa_dirty_bit[g][k]);
169
 
170
        MDFFLR #(1) dfa_dirty_bit_ff (clk, rst, dfa_dirty_bit_ld[g], 1'b0, dfa_dirty_bit_in[g][k], dfa_dirty_bit[g][k]);
171
 
172
        // generate a "row" version as well
173
        assign dfa_dirty_bit_row[k][g] = dfa_dirty_bit[g][k] & chkpt_valid_mask[g];
174
      end
175
    end
176
  endgenerate
177
 
178
  // Determine which checkpoint contains the most recent mapping for each source and the destination
179
  // TODO: For now, assume 4 checkpoints.  Find a nice way to make this general.
180
  assign ds1_src1_chkpt = (chkpt_head_ptr == 2'h0) ? (dfa_dirty_bit_row[ds1_src1_idx][0] ? 2'h0 :
181
                                                      dfa_dirty_bit_row[ds1_src1_idx][1] ? 2'h1 :
182
                                                      dfa_dirty_bit_row[ds1_src1_idx][2] ? 2'h2 : 2'h3) :
183
                          (chkpt_head_ptr == 2'h1) ? (dfa_dirty_bit_row[ds1_src1_idx][1] ? 2'h1 :
184
                                                      dfa_dirty_bit_row[ds1_src1_idx][2] ? 2'h2 :
185
                                                      dfa_dirty_bit_row[ds1_src1_idx][3] ? 2'h3 : 2'h0) :
186
                          (chkpt_head_ptr == 2'h2) ? (dfa_dirty_bit_row[ds1_src1_idx][2] ? 2'h2 :
187
                                                      dfa_dirty_bit_row[ds1_src1_idx][3] ? 2'h3 :
188
                                                      dfa_dirty_bit_row[ds1_src1_idx][0] ? 2'h0 : 2'h1) :
189
                                                     (dfa_dirty_bit_row[ds1_src1_idx][3] ? 2'h3 :
190
                                                      dfa_dirty_bit_row[ds1_src1_idx][0] ? 2'h0 :
191
                                                      dfa_dirty_bit_row[ds1_src1_idx][1] ? 2'h1 : 2'h2);
192
  assign ds1_src2_chkpt = (chkpt_head_ptr == 2'h0) ? (dfa_dirty_bit_row[ds1_src2_idx][0] ? 2'h0 :
193
                                                      dfa_dirty_bit_row[ds1_src2_idx][1] ? 2'h1 :
194
                                                      dfa_dirty_bit_row[ds1_src2_idx][2] ? 2'h2 : 2'h3) :
195
                          (chkpt_head_ptr == 2'h1) ? (dfa_dirty_bit_row[ds1_src2_idx][1] ? 2'h1 :
196
                                                      dfa_dirty_bit_row[ds1_src2_idx][2] ? 2'h2 :
197
                                                      dfa_dirty_bit_row[ds1_src2_idx][3] ? 2'h3 : 2'h0) :
198
                          (chkpt_head_ptr == 2'h2) ? (dfa_dirty_bit_row[ds1_src2_idx][2] ? 2'h2 :
199
                                                      dfa_dirty_bit_row[ds1_src2_idx][3] ? 2'h3 :
200
                                                      dfa_dirty_bit_row[ds1_src2_idx][0] ? 2'h0 : 2'h1) :
201
                                                     (dfa_dirty_bit_row[ds1_src2_idx][3] ? 2'h3 :
202
                                                      dfa_dirty_bit_row[ds1_src2_idx][0] ? 2'h0 :
203
                                                      dfa_dirty_bit_row[ds1_src2_idx][1] ? 2'h1 : 2'h2);
204
  assign ds1_dest_chkpt = (chkpt_head_ptr == 2'h0) ? (dfa_dirty_bit_row[ds1_dest_idx][0] ? 2'h0 :
205
                                                      dfa_dirty_bit_row[ds1_dest_idx][1] ? 2'h1 :
206
                                                      dfa_dirty_bit_row[ds1_dest_idx][2] ? 2'h2 : 2'h3) :
207
                          (chkpt_head_ptr == 2'h1) ? (dfa_dirty_bit_row[ds1_dest_idx][1] ? 2'h1 :
208
                                                      dfa_dirty_bit_row[ds1_dest_idx][2] ? 2'h2 :
209
                                                      dfa_dirty_bit_row[ds1_dest_idx][3] ? 2'h3 : 2'h0) :
210
                          (chkpt_head_ptr == 2'h2) ? (dfa_dirty_bit_row[ds1_dest_idx][2] ? 2'h2 :
211
                                                      dfa_dirty_bit_row[ds1_dest_idx][3] ? 2'h3 :
212
                                                      dfa_dirty_bit_row[ds1_dest_idx][0] ? 2'h0 : 2'h1) :
213
                                                     (dfa_dirty_bit_row[ds1_dest_idx][3] ? 2'h3 :
214
                                                      dfa_dirty_bit_row[ds1_dest_idx][0] ? 2'h0 :
215
                                                      dfa_dirty_bit_row[ds1_dest_idx][1] ? 2'h1 : 2'h2);
216
 
217
  // If no dirty bit set for any of the valid checkpoints, then committed copy must have latest mapping
218
  wire ds1_src1_use_rrat = ~(|dfa_dirty_bit_row[ds1_src1_idx]);
219
  wire ds1_src2_use_rrat = ~(|dfa_dirty_bit_row[ds1_src2_idx]);
220
  wire ds1_dest_use_rrat = ~(|dfa_dirty_bit_row[ds1_dest_idx]);
221
 
222
  // Generate the RAT SRAM read/write addresses and controls
223
  // Note: since tables are SRAM-based, we need to initialize the RRAT so that 
224
  // registers are mapped correctly out of reset
225
  wire [`REG_IDX_SZ-1:0] map_table_init_ctr, map_table_init_ctr_in;
226
  wire map_table_init_in = map_table_init & (map_table_init_ctr != `ARCH_REGS);
227
  MDFFR #(1) map_table_init_ff (clk, rst, 1'b1, map_table_init_in, map_table_init);
228
 
229
  assign map_table_init_ctr_in = map_table_init_ctr + `REG_IDX_SZ'h1;
230
  MDFFLR #(`REG_IDX_SZ) map_table_init_ctr_ff (clk, rst, map_table_init, `REG_IDX_SZ'h0, map_table_init_ctr_in, map_table_init_ctr);
231
 
232
  wire [`REG_IDX_SZ+`CHKPT_PTR_SZ-1:0] ds1_rat_src1_rd_addr = {ds1_src1_idx,ds1_src1_chkpt};
233
  wire [`REG_IDX_SZ+`CHKPT_PTR_SZ-1:0] ds1_rat_src2_rd_addr = {ds1_src2_idx,ds1_src2_chkpt};
234
  wire [`REG_IDX_SZ+`CHKPT_PTR_SZ-1:0] ds1_rat_dest_rd_addr = {ds1_dest_idx,ds1_dest_chkpt};
235
 
236
  // Writes need to come from DS2 stage in case we read and write the same arch. register
237
  wire                                 ds2_rat_wren, ds2_rat_wren_in;
238
  wire [`REG_IDX_SZ+`CHKPT_PTR_SZ-1:0] ds2_rat_wr_addr, ds2_rat_wr_addr_in;
239
  wire [`TAG_SZ-1:0]                   ds2_rat_wr_data;
240
 
241
  assign ds2_rat_wren_in = ds1_dest_wr;
242
  assign ds2_rat_wr_addr_in = {ds1_dest_idx,chkpt_head_ptr};
243
  MDFFR #(1) ds2_rat_wren_ff (clk, rst, 1'b0, ds2_rat_wren_in, ds2_rat_wren);
244
  MDFFR #(`REG_IDX_SZ+`CHKPT_PTR_SZ) ds2_rat_wr_addr_ff (clk, rst, 1'b0, ds2_rat_wr_addr_in, ds2_rat_wr_addr);
245
  assign ds2_rat_wr_data = ds2_dest_tag;
246
 
247
  wire [`TAG_SZ-1:0] ds2_rat_src1_rd_data, ds2_rrat_src1_rd_data;
248
  wire [`TAG_SZ-1:0] ds2_rat_src2_rd_data, ds2_rrat_src2_rd_data;
249
  wire [`TAG_SZ-1:0] ds2_rat_dest_rd_data, ds2_rrat_dest_rd_data;
250
 
251
  wire [`REG_IDX_SZ-1:0] ds_rrat_wr_addr = map_table_init ? map_table_init_ctr : rob_ds_ret_idx;
252
  wire [`TAG_SZ-1:0]     ds_rrat_wr_data = map_table_init ? map_table_init_ctr : rob_ds_ret_tag;
253
  wire                   ds_rrat_wren    = map_table_init | rob_ds_ret_valid & rob_ds_ret_dest_write;
254
 
255
  // Instantiate RAT SRAM blocks
256
  // Note that we need 3 copies for the required 3 read ports (2 source operand tag reads, 1 previous dest tag read)
257
  // Read copy 1
258
  dp_sram #(.DW(`TAG_SZ), .IW(`REG_IDX_SZ+`CHKPT_PTR_SZ)) rat0 (
259
    .clk(clk),
260
    .a_addr(ds1_rat_src1_rd_addr),   // Read port
261
    .a_dout(ds2_rat_src1_rd_data),
262
 
263
    .b_addr(ds2_rat_wr_addr),        // Write port
264
    .b_wren(ds2_rat_wren),
265
    .b_din(ds2_rat_wr_data)
266
  );
267
 
268
  // Read copy 2
269
  dp_sram #(.DW(`TAG_SZ), .IW(`REG_IDX_SZ+`CHKPT_PTR_SZ)) rat1 (
270
    .clk(clk),
271
    .a_addr(ds1_rat_src2_rd_addr),   // Read port
272
    .a_dout(ds2_rat_src2_rd_data),
273
 
274
    .b_addr(ds2_rat_wr_addr),        // Write port
275
    .b_wren(ds2_rat_wren),
276
    .b_din(ds2_rat_wr_data)
277
  );
278
 
279
  // Write copy 1
280
  dp_sram #(.DW(`TAG_SZ), .IW(`REG_IDX_SZ+`CHKPT_PTR_SZ)) rat2 (
281
    .clk(clk),
282
    .a_addr(ds1_rat_dest_rd_addr),   // Read port
283
    .a_dout(ds2_rat_dest_rd_data),
284
 
285
    .b_addr(ds2_rat_wr_addr),        // Write port
286
    .b_wren(ds2_rat_wren),
287
    .b_din(ds2_rat_wr_data)
288
  );
289
 
290
  // Instantiate tables for the committed RAT copies
291
  dp_sram #(.DW(`TAG_SZ), .IW(`REG_IDX_SZ)) rrat0 (
292
    .clk(clk),
293
    .a_addr(ds1_src1_idx),           // Read port
294
    .a_dout(ds2_rrat_src1_rd_data),
295
 
296
    .b_addr(ds_rrat_wr_addr),        // Write port  (controlled by retire)
297
    .b_wren(ds_rrat_wren),
298
    .b_din(ds_rrat_wr_data)
299
  );
300
  dp_sram #(.DW(`TAG_SZ), .IW(`REG_IDX_SZ)) rrat1 (
301
    .clk(clk),
302
    .a_addr(ds1_src2_idx),           // Read port
303
    .a_dout(ds2_rrat_src2_rd_data),
304
 
305
    .b_addr(ds_rrat_wr_addr),        // Write port  (controlled by retire)
306
    .b_wren(ds_rrat_wren),
307
    .b_din(ds_rrat_wr_data)
308
  );
309
  dp_sram #(.DW(`TAG_SZ), .IW(`REG_IDX_SZ)) rrat2 (
310
    .clk(clk),
311
    .a_addr(ds1_dest_idx),           // Read port
312
    .a_dout(ds2_rrat_dest_rd_data),
313
 
314
    .b_addr(ds_rrat_wr_addr),        // Write port  (controlled by retire)
315
    .b_wren(ds_rrat_wren),
316
    .b_din(ds_rrat_wr_data)
317
  );
318
 
319
  // Since writes to map tables occur in DS2 stage, need to detect forwarding from previous instructions
320
  wire ds1_src1_wr_fwd = (ds1_src1_idx == ds2_rat_wr_addr[`REG_IDX_SZ+`CHKPT_PTR_SZ-1:`CHKPT_PTR_SZ]) & ds2_rat_wren;
321
  wire ds1_src2_wr_fwd = (ds1_src2_idx == ds2_rat_wr_addr[`REG_IDX_SZ+`CHKPT_PTR_SZ-1:`CHKPT_PTR_SZ]) & ds2_rat_wren;
322
  wire ds1_dest_wr_fwd = (ds1_dest_idx == ds2_rat_wr_addr[`REG_IDX_SZ+`CHKPT_PTR_SZ-1:`CHKPT_PTR_SZ]) & ds2_rat_wren;
323
  wire ds2_src1_wr_fwd, ds2_src2_wr_fwd, ds2_dest_wr_fwd;
324
  MDFFR #(1) ds2_src1_wr_fwd_ff (clk, rst, 1'b0, ds1_src1_wr_fwd, ds2_src1_wr_fwd);
325
  MDFFR #(1) ds2_src2_wr_fwd_ff (clk, rst, 1'b0, ds1_src2_wr_fwd, ds2_src2_wr_fwd);
326
  MDFFR #(1) ds2_dest_wr_fwd_ff (clk, rst, 1'b0, ds1_dest_wr_fwd, ds2_dest_wr_fwd);
327
 
328
  wire [`TAG_SZ-1:0] r_ds2_rat_wr_data;
329
  wire r_ds2_wr_data_ld = ds2_rat_wren & (ds1_src1_wr_fwd | ds1_src2_wr_fwd | ds1_dest_wr_fwd);
330
  MDFFL #(`TAG_SZ) r_ds2_rat_wr_data_ff (clk, r_ds2_wr_data_ld, ds2_rat_wr_data, r_ds2_rat_wr_data);
331
 
332
  // Generate DS2 stage outputs
333
  // Mux between RRAT and RAT outputs
334
  MDFFL #(`CHKPT_PTR_SZ) ds2_chkpt_ptr_ff   (clk, ds1_valid, chkpt_head_ptr, ds2_chkpt_ptr);
335
  MDFFL #(`FL_PTR_SZ)    ds2_fl_head_ptr_ff (clk, ds1_valid, ds1_fl_head_ptr, ds2_fl_head_ptr);
336
 
337
  wire ds2_src1_use_rrat, ds2_src2_use_rrat, ds2_dest_use_rrat;
338
  MDFFLR #(1) ds2_src1_use_rrat_ff (clk, rst, ds1_valid, 1'b0, ds1_src1_use_rrat, ds2_src1_use_rrat);
339
  MDFFLR #(1) ds2_src2_use_rrat_ff (clk, rst, ds1_valid, 1'b0, ds1_src2_use_rrat, ds2_src2_use_rrat);
340
  MDFFLR #(1) ds2_dest_use_rrat_ff (clk, rst, ds1_valid, 1'b0, ds1_dest_use_rrat, ds2_dest_use_rrat);
341
  MDFFL  #(`TAG_SZ) ds2_dest_tag_ff (clk, ds1_valid, ds1_dest_tag, ds2_dest_tag);
342
 
343
  assign ds2_src1_tag     = ds2_src1_wr_fwd ? r_ds2_rat_wr_data : ds2_src1_use_rrat ? ds2_rrat_src1_rd_data : ds2_rat_src1_rd_data;
344
  assign ds2_src2_tag     = ds2_src2_wr_fwd ? r_ds2_rat_wr_data : ds2_src2_use_rrat ? ds2_rrat_src2_rd_data : ds2_rat_src2_rd_data;
345
  assign ds2_dest_tag_old = ds2_dest_wr_fwd ? r_ds2_rat_wr_data : ds2_dest_use_rrat ? ds2_rrat_dest_rd_data : ds2_rat_dest_rd_data;
346
 
347
 
348
 
349
 
350
endmodule

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.