1 /******************************************************************************
  2 * Copyright 2013, Hectic Tech (Jeff Heckey). All rights reserved
  3 ******************************************************************************/
  4 
  5 module rs #(
  6     parameter ID  = 0,    // ID to match
  7     parameter TAG = 4,    // Tag size
  8     parameter OP  = 3,    // OPCODE size
  9     parameter DATA = 32   // Data width
 10 ) (
 11     input  wire                     clk,
 12     input  wire                     rstn,
 13 
 14     input  wire [TAG-1:0]           cdb_r0_id,
 15     input  wire [DATA-1:0]          cdb_r0_data,
 16     input  wire [TAG-1:0]           cdb_r1_id,
 17     input  wire [DATA-1:0]          cdb_r1_data,
 18     input  wire [TAG-1:0]           cdb_r2_id,
 19     input  wire [DATA-1:0]          cdb_r2_data,
 20     input  wire [TAG-1:0]           cdb_a_id,
 21     input  wire [DATA-1:0]          cdb_a_data,
 22     input  wire [TAG-1:0]           cdb_m_id,
 23     input  wire [DATA-1:0]          cdb_m_data,
 24     input  wire [TAG-1:0]           cdb_l_id,
 25     input  wire [DATA-1:0]          cdb_l_data,
 26     input  wire [OP+4*TAG-1:0]      disp_bus0,
 27     input  wire [OP+4*TAG-1:0]      disp_bus1,
 28 
 29     output reg                      func_val,
 30     input  wire                     func_ack,
 31     output reg  [OP-1:0]            func_op,
 32     output reg  [DATA-1:0]          func_src1,
 33     output reg  [DATA-1:0]          func_src2
 34 );
 35 
 36 reg  [TAG-1:0]          cdb_r0_idN;
 37 reg  [DATA-1:0]         cdb_r0_dataN;
 38 reg  [TAG-1:0]          cdb_r1_idN;
 39 reg  [DATA-1:0]         cdb_r1_dataN;
 40 reg  [TAG-1:0]          cdb_r2_idN;
 41 reg  [DATA-1:0]         cdb_r2_dataN;
 42 reg  [TAG-1:0]          cdb_a_idN;
 43 reg  [DATA-1:0]         cdb_a_dataN;
 44 reg  [TAG-1:0]          cdb_m_idN;
 45 reg  [DATA-1:0]         cdb_m_dataN;
 46 reg  [TAG-1:0]          cdb_l_idN;
 47 reg  [DATA-1:0]         cdb_l_dataN;
 48 reg  [OP+4*TAG-1:0]     disp_bus0N;
 49 reg  [OP+4*TAG-1:0]     disp_bus1N;
 50 reg  [OP-1:0]           disp_op0N;
 51 reg  [TAG-1:0]          disp_rsv0N;
 52 reg  [TAG-1:0]          disp_dst0N;
 53 reg  [TAG-1:0]          disp_src01N;
 54 reg  [TAG-1:0]          disp_src02N;
 55 reg  [OP-1:0]           disp_op1N;
 56 reg  [TAG-1:0]          disp_rsv1N;
 57 reg  [TAG-1:0]          disp_dst1N;
 58 reg  [TAG-1:0]          disp_src11N;
 59 reg  [TAG-1:0]          disp_src12N;
 60 reg                     func_valN;
 61 
 62 reg  [OP-1:0]   opN, op_next, op_nextN;
 63 reg  [TAG-1:0]  src1_tag, src1_tagN, src1_tag_next, src1_tag_tempN, src1_tag_nextN;
 64 reg  [DATA-1:0] src1_dataN, src1_data_next, src1_data_nextN;
 65 reg  [TAG-1:0]  src2_tag, src2_tagN, src2_tag_next, src2_tag_tempN, src2_tag_nextN;
 66 reg  [DATA-1:0] src2_dataN, src2_data_next, src2_data_nextN;
 67 
 68 always @* begin : RS_POS_LOGIC
 69     if ( func_ack && |func_op ) begin
 70         op_next         = {OP{1'b0}};
 71         src1_tag_next   = {TAG{1'b0}};
 72         src1_data_next  = {DATA{1'b0}};
 73         src2_tag_next   = {TAG{1'b0}};
 74         src2_data_next  = {DATA{1'b0}};
 75     end
 76     else begin
 77         op_next         = func_op;
 78         src1_tag_next   = src1_tag;
 79         src1_data_next  = func_src1;
 80         src2_tag_next   = src2_tag;
 81         src2_data_next  = func_src2;
 82     end
 83 end
 84 
 85 always @* begin : RS_NEG_LATCH
 86     if ( !rstn ) begin
 87         cdb_r0_idN      <= {TAG{1'b0}};
 88         cdb_r0_dataN    <= {DATA{1'b0}};
 89         cdb_r1_idN      <= {TAG{1'b0}};
 90         cdb_r1_dataN    <= {DATA{1'b0}};
 91         cdb_r2_idN      <= {TAG{1'b0}};
 92         cdb_r2_dataN    <= {DATA{1'b0}};
 93         cdb_a_idN       <= {TAG{1'b0}};
 94         cdb_a_dataN     <= {DATA{1'b0}};
 95         cdb_m_idN       <= {TAG{1'b0}};
 96         cdb_m_dataN     <= {DATA{1'b0}};
 97         cdb_l_idN       <= {TAG{1'b0}};
 98         cdb_l_dataN     <= {DATA{1'b0}};
 99         disp_bus0N      <= {OP+4*TAG{1'b0}};
100         disp_bus1N      <= {OP+4*TAG{1'b0}};
101 
102         opN             <= {OP{1'b0}};
103         src1_tagN       <= {TAG{1'b0}};
104         src1_dataN      <= {DATA{1'b0}};
105         src2_tagN       <= {TAG{1'b0}};
106         src2_dataN      <= {DATA{1'b0}};
107     end
108     else begin
109         if ( !clk ) begin
110             // Latch buses on negedge to use for logic; propagation is assumed 
111             // to be 1/2 clock cycle
112             cdb_r0_idN      <= cdb_r0_id;
113             cdb_r0_dataN    <= cdb_r0_data;
114             cdb_r1_idN      <= cdb_r1_id;
115             cdb_r1_dataN    <= cdb_r1_data;
116             cdb_r2_idN      <= cdb_r2_id;
117             cdb_r2_dataN    <= cdb_r2_data;
118             cdb_a_idN       <= cdb_a_id;
119             cdb_a_dataN     <= cdb_a_data;
120             cdb_m_idN       <= cdb_m_id;
121             cdb_m_dataN     <= cdb_m_data;
122             cdb_l_idN       <= cdb_l_id;
123             cdb_l_dataN     <= cdb_l_data;
124             disp_bus0N      <= disp_bus0;
125             disp_bus1N      <= disp_bus1;
126 
127             opN             <= op_next;
128             src1_tagN       <= src1_tag_next;
129             src1_dataN      <= src1_data_next;
130             src2_tagN       <= src2_tag_next;
131             src2_dataN      <= src2_data_next;
132         end
133     end
134 end
135 
136 always @* begin : RS_NEG_LOGIC
137     {disp_rsv0N,
138      disp_op0N,
139      disp_dst0N,
140      disp_src01N,
141      disp_src02N} = disp_bus0N;
142     {disp_rsv1N,
143      disp_op1N,
144      disp_dst1N,
145      disp_src11N,
146      disp_src12N} = disp_bus1N;
147 
148     // Load next op if available
149     if ( disp_rsv0N == ID ) begin
150         op_nextN        = disp_op0N;
151         // Use temp tags for later eval
152         src1_tag_tempN  = disp_src01N;
153         src2_tag_tempN  = disp_src02N;
154     end
155     else if ( disp_rsv1N == ID ) begin
156         op_nextN        = disp_op1N;
157         src1_tag_tempN  = disp_src11N;
158         src2_tag_tempN  = disp_src12N;
159     end
160     else begin
161         // otherwise keep current value
162         op_nextN        = opN;
163         src1_tag_tempN  = src1_tagN;
164         src2_tag_tempN  = src2_tagN;
165     end
166 
167     // SRC1: check temp tags for data on the bus and load if present
168     if ( ~|src1_tag_tempN ) begin
169         src1_tag_nextN  = {TAG{1'b0}};
170         src1_data_nextN = src1_dataN;
171     end
172     else if ( src1_tag_tempN == cdb_r0_idN ) begin
173         src1_tag_nextN  = {TAG{1'b0}};
174         src1_data_nextN = cdb_r0_dataN;
175     end
176     else if ( src1_tag_tempN == cdb_r1_idN ) begin
177         src1_tag_nextN  = {TAG{1'b0}};
178         src1_data_nextN = cdb_r1_dataN;
179     end
180     else if ( src1_tag_tempN == cdb_r2_idN ) begin
181         src1_tag_nextN  = {TAG{1'b0}};
182         src1_data_nextN = cdb_r2_dataN;
183     end
184     else if ( src1_tag_tempN == cdb_a_idN ) begin
185         src1_tag_nextN  = {TAG{1'b0}};
186         src1_data_nextN = cdb_a_dataN;
187     end
188     else if ( src1_tag_tempN == cdb_m_idN ) begin
189         src1_tag_nextN  = {TAG{1'b0}};
190         src1_data_nextN = cdb_m_dataN;
191     end
192     else if ( src1_tag_tempN == cdb_l_idN ) begin
193         src1_tag_nextN  = {TAG{1'b0}};
194         src1_data_nextN = cdb_l_dataN;
195     end
196     else begin
197         // save temp tag and zero data if not available
198         src1_tag_nextN  = src1_tag_tempN;
199         src1_data_nextN = {DATA{1'b0}};
200     end
201 
202     // SRC2: check temp tags for data on the bus and load if present
203     if ( ~|src2_tag_tempN ) begin
204         src2_tag_nextN  = {TAG{1'b0}};
205         src2_data_nextN = src2_dataN;
206     end
207     else if ( src2_tag_tempN == cdb_r0_idN ) begin
208         src2_tag_nextN  = {TAG{1'b0}};
209         src2_data_nextN = cdb_r0_dataN;
210     end
211     else if ( src2_tag_tempN == cdb_r1_idN ) begin
212         src2_tag_nextN  = {TAG{1'b0}};
213         src2_data_nextN = cdb_r1_dataN;
214     end
215     else if ( src2_tag_tempN == cdb_r2_idN ) begin
216         src2_tag_nextN  = {TAG{1'b0}};
217         src2_data_nextN = cdb_r2_dataN;
218     end
219     else if ( src2_tag_tempN == cdb_a_idN ) begin
220         src2_tag_nextN  = {TAG{1'b0}};
221         src2_data_nextN = cdb_a_dataN;
222     end
223     else if ( src2_tag_tempN == cdb_m_idN ) begin
224         src2_tag_nextN  = {TAG{1'b0}};
225         src2_data_nextN = cdb_m_dataN;
226     end
227     else if ( src2_tag_tempN == cdb_l_idN ) begin
228         src2_tag_nextN  = {TAG{1'b0}};
229         src2_data_nextN = cdb_l_dataN;
230     end
231     else begin
232         // save temp tag and zero data if not available
233         src2_tag_nextN  = src2_tag_tempN;
234         src2_data_nextN = {DATA{1'b0}};
235     end
236 
237     func_valN   = |op_nextN && ~|src1_tag_nextN && ~|src2_tag_nextN;
238 end
239 
240 always @* begin : RS_POS_LATCHES
241     if ( !rstn ) begin
242         func_val    <= 1'b0;
243         func_op     <= {OP{1'b0}};
244         src1_tag    <= {TAG{1'b0}};
245         func_src1   <= {TAG{1'b0}};
246         src2_tag    <= {TAG{1'b0}};
247         func_src2   <= {TAG{1'b0}};
248     end
249     else begin
250         if ( clk ) begin
251             func_val    <= func_valN;
252             func_op     <= op_nextN;
253             src1_tag    <= src1_tag_nextN;
254             func_src1   <= src1_data_nextN;
255             src2_tag    <= src2_tag_nextN;
256             func_src2   <= src2_data_nextN;
257         end
258     end
259 end
260 
261 endmodule
262