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

Subversion Repositories hive

[/] [hive/] [trunk/] [v04.05/] [reg_base.v] - Blame information for rev 10

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 ericw
/*
2
--------------------------------------------------------------------------------
3
 
4
Module: reg_base.v
5
 
6
Function:
7
- Single base processor register w/ multiple type & input options (synchronous).
8
 
9
Instantiates:
10
- Nothing.
11
 
12
Notes:
13
- Init value for each latched bit.
14
- LIVE_MASK[i]=1 indicates live bit.
15
- LIVE_MASK[i]=0 indicates dead bit, reads zero.
16
- Optional resync (2x registering) of inputs.
17
- Optional edge detection (rising) of inputs.
18
- rd_data_o is driven non-zero if there is an address match, regardless of
19
  state of rd_i.
20
- Use large OR gate to combine multiple register set read data.
21
 
22
OUT_MODE:
23
- "ZERO" : zero out
24
- "THRU" : no latch, direct connect
25
- "LTCH" : write latch
26
- "LOOP" : no latch, output selected read data
27
 
28
READ_MODE:
29
- "THRU" : no latch, direct connect
30
- "CORD" : set on input one, clear on read
31
- "COW1" : set on input one, clear on write one
32
- "DFFE" : D type flip flop with enable
33
- "LOOP" : no latch, read selected output data
34
 
35
--------------------------------------------------------------------------------
36
*/
37
 
38
 
39
module reg_base
40
        #(
41
        parameter       integer                                                 DATA_W                  = 8,            // data width (bits)
42
        parameter       integer                                                 ADDR_W                  = 4,            // address width (bits)
43
        parameter       [ADDR_W-1:0]                                     ADDRESS                 = 0,             // address this register responds to
44
        parameter                                                                               OUT_MODE                        = "LOOP",       // modes are: "ZERO", "THRU", "LTCH", "LOOP"
45
        parameter                                                                               READ_MODE               = "COW1",       // modes are: "THRU", "CORD", "COW1", "DFFE", "LOOP"
46
        parameter       [DATA_W-1:0]                                     LIVE_MASK               = { DATA_W{ 1'b1 } },   // 1=live data bit, 0=dead (0)
47
        parameter                                                                               IN_RESYNC               = 0,             // 1=resync (double clock) input, 0=no resync
48
        parameter                                                                               IN_EDGE                 = 0,             // 1=edge (rising) sensitive, 0=level sensitive
49
        parameter       [DATA_W-1:0]                                     RESET_VAL               = 0              // reset value of latched data
50
        )
51
        (
52
        // clocks & resets
53
        input                   wire                                                            clk_i,                                          // clock
54
        input                   wire                                                            rst_i,                                          // async. reset, active high
55
        // bus interface
56
        input                   wire    [ADDR_W-1:0]                     addr_i,                                         // address
57
        input                   wire                                                            wr_i,                                                   // data write enable, active high
58
        input                   wire                                                            rd_i,                                                   // data read enable, active high
59
        input                   wire    [DATA_W-1:0]                     wr_data_i,                                      // write data
60
        output          wire    [DATA_W-1:0]                     rd_data_o,                                      // read data
61
        // register interface
62
        output          wire                                                            reg_wr_o,                                       // reg write active, active high
63
        output          wire                                                            reg_rd_o,                                       // reg read active, active high
64
        input                   wire                                                            reg_en_i,                                       // reg enable, active high ("DFFE" mode only)
65
        input                   wire    [DATA_W-1:0]                     reg_data_i,                                     // reg data in
66
        output          wire    [DATA_W-1:0]                     reg_data_o                                      // reg data out
67
        );
68
 
69
 
70
        /*
71
        ----------------------
72
        -- internal signals --
73
        ----------------------
74
        */
75
        wire                                                                                            addr_match;
76
        genvar                                                                                  i;
77
        wire                                    [DATA_W-1:0]                     in_data, out_data, rd_data;
78
 
79
 
80
        /*
81
        ================
82
        == code start ==
83
        ================
84
        */
85
 
86
 
87
        // check for address match
88
        assign addr_match = ( addr_i == ADDRESS[ADDR_W-1:0] );
89
 
90
        // decode read & write
91
        assign reg_rd_o = ( rd_i & addr_match );
92
        assign reg_wr_o = ( wr_i & addr_match );
93
 
94
 
95
        // generate output logic based on mode
96
        generate
97
                for ( i=0; i<DATA_W; i=i+1 ) begin : output_loop
98
                        if ( LIVE_MASK[i] ) begin  // live bit
99
                                case ( OUT_MODE )
100
                                        "ZERO" : begin
101
                                                assign out_data[i] = 1'b0;
102
                                        end
103
                                        "THRU" : begin
104
                                                assign out_data[i] = wr_data_i[i];
105
                                        end
106
                                        "LTCH" : begin
107
                                                reg reg_bit;
108
                                                always @ ( posedge clk_i or posedge rst_i ) begin
109
                                                        if ( rst_i ) begin
110
                                                                reg_bit <= RESET_VAL[i];
111
                                                        end else begin
112
                                                                if ( reg_wr_o ) begin
113
                                                                        reg_bit <= wr_data_i[i];
114
                                                                end
115
                                                        end
116
                                                end
117
                                                assign out_data[i] = reg_bit;
118
                                        end
119
                                        "LOOP" : begin
120
                                                assign out_data[i] = rd_data[i];
121
                                        end
122
                                        default : begin  // unknown mode!
123
                                                initial $display ( "OUT_MODE %s does not exist!", OUT_MODE );
124
                                        end
125
                                endcase
126
                        end else begin  // dead bit
127
                                assign out_data[i] = 1'b0;
128
                        end
129
                end
130
        endgenerate
131
 
132
 
133
        // generate optional input resync & edge detect logic
134
        generate
135
                for ( i=0; i<DATA_W; i=i+1 ) begin : input_processing_loop
136
                        if ( LIVE_MASK[i] ) begin  // live bit
137
                                wire in_2;
138
                                if ( IN_RESYNC ) begin
139
                                        reg in_0, in_1;
140
                                        always @ ( posedge clk_i or posedge rst_i ) begin
141
                                                if ( rst_i ) begin
142
                                                        in_0 <= 1'b0;
143
                                                        in_1 <= 1'b0;
144
                                                end else begin
145
                                                        in_0 <= reg_data_i[i];
146
                                                        in_1 <= in_0;
147
                                                end
148
                                        end
149
                                        assign in_2 = in_1;
150
                                end else begin
151
                                        assign in_2 = reg_data_i[i];
152
                                end
153
                                //
154
                                if ( IN_EDGE ) begin
155
                                        reg in_3;
156
                                        always @ ( posedge clk_i or posedge rst_i ) begin
157
                                                if ( rst_i ) begin
158
                                                        in_3 <= 1'b0;
159
                                                end else begin
160
                                                        in_3 <= in_2;
161
                                                end
162
                                        end
163
                                        assign in_data[i] = ( in_2 & ~in_3 );
164
                                end else begin
165
                                        assign in_data[i] = in_2;
166
                                end
167
                        end else begin  // dead bit
168
                                assign in_data[i] = 1'b0;
169
                        end  // endif
170
                end  // endfor
171
        endgenerate
172
 
173
 
174
        // generate read logic based on mode
175
        generate
176
                for ( i=0; i<DATA_W; i=i+1 ) begin : read_loop
177
                        if ( LIVE_MASK[i] ) begin  // live bit
178
                                case ( READ_MODE )
179
                                        "THRU" : begin
180
                                                assign rd_data[i] = in_data[i];
181
                                        end
182
                                        "CORD" : begin
183
                                                reg reg_bit;
184
                                                always @ ( posedge clk_i or posedge rst_i ) begin
185
                                                        if ( rst_i ) begin
186
                                                                reg_bit <= RESET_VAL[i];
187
                                                        end else begin
188
                                                                if ( reg_rd_o ) begin
189
                                                                        reg_bit <= 1'b0;
190
                                                                end else begin
191
                                                                        reg_bit <= reg_bit | in_data[i];
192
                                                                end
193
                                                        end
194
                                                end
195
                                                assign rd_data[i] = reg_bit;
196
                                        end
197
                                        "COW1" : begin
198
                                                reg reg_bit;
199
                                                always @ ( posedge clk_i or posedge rst_i ) begin
200
                                                        if ( rst_i ) begin
201
                                                                reg_bit <= RESET_VAL[i];
202
                                                        end else begin
203
                                                                if ( reg_wr_o ) begin
204
                                                                        reg_bit <= reg_bit & ~wr_data_i[i];
205
                                                                end else begin
206
                                                                        reg_bit <= reg_bit | in_data[i];
207
                                                                end
208
                                                        end
209
                                                end
210
                                                assign rd_data[i] = reg_bit;
211
                                        end
212
                                        "DFFE" : begin
213
                                                reg reg_bit;
214
                                                always @ ( posedge clk_i or posedge rst_i ) begin
215
                                                        if ( rst_i ) begin
216
                                                                reg_bit <= RESET_VAL[i];
217
                                                        end else if ( reg_en_i ) begin
218
                                                                reg_bit <= in_data[i];
219
                                                        end
220
                                                end
221
                                                assign rd_data[i] = reg_bit;
222
                                        end
223
                                        "LOOP" : begin
224
                                                assign rd_data[i] = out_data[i];
225
                                        end
226
                                        default : begin  // unknown mode!
227
                                                initial $display ( "RD_MODE %s does not exist!", RD_MODE );
228
                                        end
229
                                endcase
230
                        end else begin  // dead bit
231
                                assign rd_data[i] = 1'b0;
232
                        end
233
                end
234
        endgenerate
235
 
236
 
237
        // drive outputs
238
        assign rd_data_o = ( addr_match ) ? rd_data : 1'b0;
239
        assign reg_data_o = out_data;
240
 
241
 
242
endmodule

powered by: WebSVN 2.1.0

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