1 /******************************************************************************
  2 * Copyright 2013, Hectic Tech (Jeff Heckey). All rights reserved
  3 ******************************************************************************/
  4 
  5 module regstat #(
  6     parameter TAG = 4
  7 ) (
  8     input  wire                     clk,
  9     input  wire                     rstn,
 10 
 11     input  wire [TAG-1:0]           disp0_dst,
 12     input  wire [TAG-1:0]           disp0_rsv,
 13     input  wire [TAG-1:0]           disp1_dst,
 14     input  wire [TAG-1:0]           disp1_rsv,
 15 
 16     input  wire [TAG-1:0]           cdb_a_id,
 17     input  wire [TAG-1:0]           cdb_m_id,
 18     input  wire [TAG-1:0]           cdb_l_id,
 19     input  wire [TAG-1:0]           cdb_s_id,
 20 
 21     output reg  [7:0]               regstat_busy,
 22     output reg  [4*TAG-1:0]         regstat_remap
 23 );
 24 
 25 // Register and reservation station tags
 26 localparam R0 = 4'd4,
 27            R1 = 4'd5,
 28            R2 = 4'd6,
 29            R3 = 4'd7,
 30            A0 = 4'd8,
 31            A1 = 4'd9,
 32            M0 = 4'd10,
 33            M1 = 4'd11,
 34            L0 = 4'd12,
 35            L1 = 4'd13,
 36            S0 = 4'd14,
 37            S1 = 4'd15;
 38 
 39 // Register and reservation station tag headers
 40 localparam RH = 2'b01,
 41            AH = 3'b100,
 42            MH = 3'b101,
 43            LH = 3'b110,
 44            SH = 3'b111;
 45 
 46 reg [7:0]           regstat_busyN, regstat_busy_next;
 47 reg [4*TAG-1:0]     regstat_remapN, regstat_remap_next;
 48 
 49 reg [TAG-1:0]       disp0_dstN;
 50 reg [TAG-1:0]       disp0_rsvN;
 51 reg [TAG-1:0]       disp1_dstN;
 52 reg [TAG-1:0]       disp1_rsvN;
 53 
 54 reg [TAG-1:0]       cdb_a_idN;
 55 reg [TAG-1:0]       cdb_m_idN;
 56 reg [TAG-1:0]       cdb_l_idN;
 57 reg [TAG-1:0]       cdb_s_idN;
 58 
 59 // No posedege logic -- assumed entire pos phase for bus propagation
 60 
 61 always @* begin : REGSTAT_NEG_LATCHES
 62     if ( !rstn ) begin
 63         regstat_busyN   <= {TAG-1{1'b0}};
 64         regstat_remapN  <= {4*TAG{1'b0}};
 65 
 66         disp0_dstN      <= {TAG{1'b0}};
 67         disp0_rsvN      <= {TAG{1'b0}};
 68         disp1_dstN      <= {TAG{1'b0}};
 69         disp1_rsvN      <= {TAG{1'b0}};
 70 
 71         cdb_a_idN       <= {TAG{1'b0}};
 72         cdb_m_idN       <= {TAG{1'b0}};
 73         cdb_l_idN       <= {TAG{1'b0}};
 74         cdb_s_idN       <= {TAG{1'b0}};
 75     end
 76     else begin
 77         if ( !clk ) begin
 78             regstat_busyN   <= regstat_busy;
 79             regstat_remapN  <= regstat_remap;
 80 
 81             disp0_dstN      <= disp0_dst;
 82             disp0_rsvN      <= disp0_rsv;
 83             disp1_dstN      <= disp1_dst;
 84             disp1_rsvN      <= disp1_rsv;
 85 
 86             cdb_a_idN       <= cdb_a_id;
 87             cdb_m_idN       <= cdb_m_id;
 88             cdb_l_idN       <= cdb_l_id;
 89             cdb_s_idN       <= cdb_s_id;
 90         end
 91     end
 92 end
 93 
 94 integer i;
 95 
 96 always @* begin : REGSTAT_POS_LOGIC
 97     // Update each register's mapping
 98     for ( i=0; i<4; i=i+1 ) begin
 99         regstat_remap_next[i*TAG +: TAG] = (disp1_dst == {RH,i[1:0]}) ? disp1_rsv                       // Rename to rsv
100                                            : (disp0_dst == {RH,i[1:0]}) ? disp0_rsv                     // Rename to rsv
101                                            : (regstat_remapN[i*TAG +: TAG] == cdb_a_idN) ? {TAG{1'b0}}  // Tag seen, clear
102                                            : (regstat_remapN[i*TAG +: TAG] == cdb_m_idN) ? {TAG{1'b0}}  // Tag seen, clear
103                                            : (regstat_remapN[i*TAG +: TAG] == cdb_l_idN) ? {TAG{1'b0}}  // Tag seen, clear
104                                            : regstat_remapN[i*TAG +: TAG];                              // Default to original
105     end
106 
107     // set busy for any incoming dispructions, clear if received
108     regstat_busy_next[A0-8] = (disp0_rsv == A0)      ? 1'b1
109                               : (disp1_rsv == A0)    ? 1'b1
110                               : (cdb_a_idN == A0)    ? 1'b0
111                               : regstat_busyN[A0-8];
112     regstat_busy_next[A1-8] = (disp0_rsv == A1)      ? 1'b1
113                               : (disp1_rsv == A1)    ? 1'b1
114                               : (cdb_a_idN == A1)    ? 1'b0
115                               : regstat_busyN[A1-8];
116     regstat_busy_next[M0-8] = (disp0_rsv == M0)      ? 1'b1
117                               : (disp1_rsv == M0)    ? 1'b1
118                               : (cdb_m_idN == M0)    ? 1'b0
119                               : regstat_busyN[M0-8];
120     regstat_busy_next[M1-8] = (disp0_rsv == M1)      ? 1'b1
121                               : (disp1_rsv == M1)    ? 1'b1
122                               : (cdb_m_idN == M1)    ? 1'b0
123                               : regstat_busyN[M1-8];
124     regstat_busy_next[L0-8] = (disp0_rsv == L0)      ? 1'b1
125                               : (disp1_rsv == L0)    ? 1'b1
126                               : (cdb_l_idN == L0)    ? 1'b0
127                               : regstat_busyN[L0-8];
128     regstat_busy_next[L1-8] = (disp0_rsv == L1)      ? 1'b1
129                               : (disp1_rsv == L1)    ? 1'b1
130                               : (cdb_l_idN == L1)    ? 1'b0
131                               : regstat_busyN[L1-8];
132     regstat_busy_next[S0-8] = (disp0_rsv == S0)      ? 1'b1
133                               : (disp1_rsv == S0)    ? 1'b1
134                               : (cdb_s_idN == S0)    ? 1'b0
135                               : regstat_busyN[S0-8];
136     regstat_busy_next[S1-8] = (disp0_rsv == S1)      ? 1'b1
137                               : (disp1_rsv == S1)    ? 1'b1
138                               : (cdb_s_idN == S1)    ? 1'b0
139                               : regstat_busyN[S1-8];
140 end
141 
142 always @* begin : REGSTAT_POS_LATCHES
143     if ( !rstn ) begin
144         regstat_busy    <= {TAG-1{1'b0}};
145         regstat_remap   <= {4*TAG{1'b0}};
146     end
147     else begin
148         if ( clk ) begin
149             regstat_busy    <= regstat_busy_next;
150             regstat_remap   <= regstat_remap_next;
151         end
152     end
153 end
154 
155 endmodule
156