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

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [amber23/] [a23_ram_register_bank.v] - Blame information for rev 82

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 73 csantifort
//////////////////////////////////////////////////////////////////
2
//                                                              //
3
//  RAM-based register Bank for Amber Core                      //
4
//                                                              //
5
//  This file is part of the Amber project                      //
6
//  http://www.opencores.org/project,amber                      //
7
//                                                              //
8
//  Description                                                 //
9
//  Contains 37 32-bit registers, 16 of which are visible       //
10
//  ina any one operating mode.                                 //
11
//  The block is designed using syncronous RAM primitive,       //
12
//  and fits well into an FPGA design                           //
13
//                                                              //
14
//  Author(s):                                                  //
15
//      - Dmitry Tarnyagin, dmitry.tarnyagin@lockless.no        //
16
//                                                              //
17
//////////////////////////////////////////////////////////////////
18
//                                                              //
19
// Copyright (C) 2010 Authors and OPENCORES.ORG                 //
20
//                                                              //
21
// This source file may be used and distributed without         //
22
// restriction provided that this copyright statement is not    //
23
// removed from the file and that any derivative work contains  //
24
// the original copyright notice and the associated disclaimer. //
25
//                                                              //
26
// This source file is free software; you can redistribute it   //
27
// and/or modify it under the terms of the GNU Lesser General   //
28
// Public License as published by the Free Software Foundation; //
29
// either version 2.1 of the License, or (at your option) any   //
30
// later version.                                               //
31
//                                                              //
32
// This source is distributed in the hope that it will be       //
33
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
34
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
35
// PURPOSE.  See the GNU Lesser General Public License for more //
36
// details.                                                     //
37
//                                                              //
38
// You should have received a copy of the GNU Lesser General    //
39
// Public License along with this source; if not, download it   //
40
// from http://www.opencores.org/lgpl.shtml                     //
41
//                                                              //
42
//////////////////////////////////////////////////////////////////
43
 
44
module a23_ram_register_bank (
45
 
46
input                       i_clk,
47
input                       i_fetch_stall,
48
 
49
input       [1:0]           i_mode_exec,            // registered cpu mode from execution stage
50
input       [1:0]           i_mode_exec_nxt,        // 1 periods delayed from i_mode_idec
51
                                                    // Used for register reads
52
input       [1:0]           i_mode_rds_exec,        // Use raw version in this implementation,
53
                                                    // includes i_user_mode_regs_store
54
input                       i_user_mode_regs_load,
55
input       [3:0]           i_rm_sel,
56
input       [3:0]           i_rds_sel,
57
input       [3:0]           i_rn_sel,
58
 
59
input                       i_pc_wen,
60
input       [3:0]           i_reg_bank_wsel,
61
 
62
input       [23:0]          i_pc,                   // program counter [25:2]
63
input       [31:0]          i_reg,
64
 
65
input       [3:0]           i_status_bits_flags,
66
input                       i_status_bits_irq_mask,
67
input                       i_status_bits_firq_mask,
68
 
69
output      [31:0]          o_rm,
70
output      [31:0]          o_rs,
71
output      [31:0]          o_rd,
72
output      [31:0]          o_rn,
73
output      [31:0]          o_pc
74
 
75
);
76
 
77 82 csantifort
`include "a23_localparams.vh"
78
`include "a23_functions.vh"
79 73 csantifort
 
80
wire  [1:0]  mode_idec;
81
wire  [1:0]  mode_exec;
82
wire  [1:0]  mode_rds;
83
 
84
wire  [4:0]  rm_addr;
85
wire  [4:0]  rds_addr;
86
wire  [4:0]  rn_addr;
87
wire  [4:0]  wr_addr;
88
 
89
// Register pool in embedded ram memory
90
reg   [31:0] reg_ram_n[31:0];
91
reg   [31:0] reg_ram_m[31:0];
92
reg   [31:0] reg_ram_ds[31:0];
93
 
94
wire  [31:0] rds_out;
95
wire  [31:0] rm_out;
96
wire  [31:0] rn_out;
97
 
98
// Synchronous ram input buffering
99
reg   [4:0]  rm_addr_reg;
100
reg   [4:0]  rds_addr_reg;
101
reg   [4:0]  rn_addr_reg;
102
 
103
// User Mode Registers
104
reg   [23:0] r15 = 24'hc0_ffee;
105
 
106
wire  [31:0] r15_out_rm;
107
wire  [31:0] r15_out_rm_nxt;
108
wire  [31:0] r15_out_rn;
109
 
110
// r15 selectors
111
reg          rn_15 = 1'b0;
112
reg          rm_15 = 1'b0;
113
reg          rds_15 = 1'b0;
114
 
115
// Write Enables from execute stage
116
assign mode_idec = i_mode_exec_nxt & ~{2{i_user_mode_regs_load}};
117
assign wr_addr = reg_addr(mode_idec, i_reg_bank_wsel);
118
 
119
// Read Enables from stage 1 (fetch)
120
assign mode_exec = i_mode_exec_nxt;
121
assign rm_addr = reg_addr(mode_exec, i_rm_sel);
122
assign rn_addr = reg_addr(mode_exec, i_rn_sel);
123
 
124
// Rds
125
assign mode_rds = i_mode_rds_exec;
126
assign rds_addr = reg_addr(mode_rds, i_rds_sel);
127
 
128
 
129
// ========================================================
130
// r15 Register Read based on Mode
131
// ========================================================
132
assign r15_out_rm     = { i_status_bits_flags,
133
                          i_status_bits_irq_mask,
134
                          i_status_bits_firq_mask,
135
                          r15,
136
                          i_mode_exec};
137
 
138
assign r15_out_rm_nxt = { i_status_bits_flags,
139
                          i_status_bits_irq_mask,
140
                          i_status_bits_firq_mask,
141
                          i_pc,
142
                          i_mode_exec};
143
 
144
assign r15_out_rn     = {6'd0, r15, 2'd0};
145
 
146
 
147
// ========================================================
148
// Program Counter out
149
// ========================================================
150
assign o_pc = r15_out_rn;
151
 
152
// ========================================================
153
// Rm Selector
154
// ========================================================
155
assign rm_out = reg_ram_m[rm_addr_reg];
156
 
157
assign o_rm =   rm_15 ?                         r15_out_rm :
158
                                                rm_out;
159
 
160
// ========================================================
161
// Rds Selector
162
// ========================================================
163
assign rds_out = reg_ram_ds[rds_addr_reg];
164
 
165
assign o_rs =   rds_15  ?                       r15_out_rn :
166
                                                rds_out;
167
 
168
// ========================================================
169
// Rd Selector
170
// ========================================================
171
assign o_rd =   rds_15  ?                       r15_out_rm_nxt :
172
                                                rds_out;
173
 
174
// ========================================================
175
// Rn Selector
176
// ========================================================
177
assign rn_out = reg_ram_n[rn_addr_reg];
178
 
179
assign o_rn =   rn_15  ?                        r15_out_rn :
180
                                                rn_out;
181
// ========================================================
182
// Register Update
183
// ========================================================
184
always @ ( posedge i_clk )
185
    if (!i_fetch_stall)
186
        begin
187
 
188
        // Register write.
189
        // Actually the code is synthesed as a syncronous ram
190
        // with an additional  pass-through multiplexor for
191
        // read-when-write handling.
192
        reg_ram_n[wr_addr]      <= i_reg;
193
        reg_ram_m[wr_addr]      <= i_reg;
194
        reg_ram_ds[wr_addr]     <= i_reg;
195
        r15                     <= i_pc_wen ? i_pc : r15;
196
 
197
        // The latching is actually implemented in a hard block.
198
        rn_addr_reg             <= rn_addr;
199
        rm_addr_reg             <= rm_addr;
200
        rds_addr_reg            <= rds_addr;
201
 
202
        rn_15                   <= i_rn_sel == 4'hF;
203
        rm_15                   <= i_rm_sel == 4'hF;
204
        rds_15                  <= i_rds_sel == 4'hF;
205
        end
206
 
207
// ========================================================
208
// Register mapping:
209
// ========================================================
210
// 0xxxx : r0 - r14
211
// 10xxx : r8_firq - r14_firq
212
// 110xx : r13_irq - r14_irq
213
// 111xx : r13_svc - r14_svc
214
 
215
function [4:0] reg_addr;
216
input [1:0] mode;
217
input [3:0] sel;
218
begin
219
        casez ({mode, sel}) // synthesis full_case parallel_case
220
                6'b??0???:       reg_addr = {1'b0, sel};         // r0 - r7
221
                6'b1?1100:      reg_addr = {1'b0, sel};         // irq and svc r12
222
                6'b001???:      reg_addr = {1'b0, sel};         // user r8 - r14
223
                6'b011???:      reg_addr = {2'b10, sel[2:0]};    // fiq r8-r14
224
                6'b1?10??:      reg_addr = {1'b0, sel};         // irq and svc r8-r11
225
                6'b101101:      reg_addr = {3'b110, sel[1:0]};   // irq r13
226
                6'b101110:      reg_addr = {3'b110, sel[1:0]};   // irq r14
227
                6'b101111:      reg_addr = {3'b110, sel[1:0]};   // irq r15, just to make the case full
228
                6'b111101:      reg_addr = {3'b111, sel[1:0]};   // svc r13
229
                6'b111110:      reg_addr = {3'b111, sel[1:0]};   // svc r14
230
                6'b111111:      reg_addr = {3'b111, sel[1:0]};   // svc r15, just to make the case full
231
        endcase
232
end
233
endfunction
234
 
235
// synthesis translate_off
236
// To be used as probes...
237
wire [31:0] r0;
238
wire [31:0] r1;
239
wire [31:0] r2;
240
wire [31:0] r3;
241
wire [31:0] r4;
242
wire [31:0] r5;
243
wire [31:0] r6;
244
wire [31:0] r7;
245
wire [31:0] r8;
246
wire [31:0] r9;
247
wire [31:0] r10;
248
wire [31:0] r11;
249
wire [31:0] r12;
250
wire [31:0] r13;
251
wire [31:0] r14;
252
wire [31:0] r13_svc;
253
wire [31:0] r14_svc;
254
wire [31:0] r13_irq;
255
wire [31:0] r14_irq;
256
wire [31:0] r8_firq;
257
wire [31:0] r9_firq;
258
wire [31:0] r10_firq;
259
wire [31:0] r11_firq;
260
wire [31:0] r12_firq;
261
wire [31:0] r13_firq;
262
wire [31:0] r14_firq;
263
wire [31:0] r0_out;
264
wire [31:0] r1_out;
265
wire [31:0] r2_out;
266
wire [31:0] r3_out;
267
wire [31:0] r4_out;
268
wire [31:0] r5_out;
269
wire [31:0] r6_out;
270
wire [31:0] r7_out;
271
wire [31:0] r8_out;
272
wire [31:0] r9_out;
273
wire [31:0] r10_out;
274
wire [31:0] r11_out;
275
wire [31:0] r12_out;
276
wire [31:0] r13_out;
277
wire [31:0] r14_out;
278
 
279
assign r0  = reg_ram_m[ 0];
280
assign r1  = reg_ram_m[ 1];
281
assign r2  = reg_ram_m[ 2];
282
assign r3  = reg_ram_m[ 3];
283
assign r4  = reg_ram_m[ 4];
284
assign r5  = reg_ram_m[ 5];
285
assign r6  = reg_ram_m[ 6];
286
assign r7  = reg_ram_m[ 7];
287
assign r8  = reg_ram_m[ 8];
288
assign r9  = reg_ram_m[ 9];
289
assign r10 = reg_ram_m[10];
290
assign r11 = reg_ram_m[11];
291
assign r12 = reg_ram_m[12];
292
assign r13 = reg_ram_m[13];
293
assign r14 = reg_ram_m[14];
294
assign r13_svc  = reg_ram_m[29];
295
assign r14_svc  = reg_ram_m[30];
296
assign r13_irq  = reg_ram_m[25];
297
assign r14_irq  = reg_ram_m[26];
298
assign r8_firq  = reg_ram_m[16];
299
assign r9_firq  = reg_ram_m[17];
300
assign r10_firq = reg_ram_m[18];
301
assign r11_firq = reg_ram_m[19];
302
assign r12_firq = reg_ram_m[20];
303
assign r13_firq = reg_ram_m[21];
304
assign r14_firq = reg_ram_m[22];
305
assign r0_out  = reg_ram_m[reg_addr(mode_exec,  0)];
306
assign r1_out  = reg_ram_m[reg_addr(mode_exec,  1)];
307
assign r2_out  = reg_ram_m[reg_addr(mode_exec,  2)];
308
assign r3_out  = reg_ram_m[reg_addr(mode_exec,  3)];
309
assign r4_out  = reg_ram_m[reg_addr(mode_exec,  4)];
310
assign r5_out  = reg_ram_m[reg_addr(mode_exec,  5)];
311
assign r6_out  = reg_ram_m[reg_addr(mode_exec,  6)];
312
assign r7_out  = reg_ram_m[reg_addr(mode_exec,  7)];
313
assign r8_out  = reg_ram_m[reg_addr(mode_exec,  8)];
314
assign r9_out  = reg_ram_m[reg_addr(mode_exec,  9)];
315
assign r10_out = reg_ram_m[reg_addr(mode_exec, 10)];
316
assign r11_out = reg_ram_m[reg_addr(mode_exec, 11)];
317
assign r12_out = reg_ram_m[reg_addr(mode_exec, 12)];
318
assign r13_out = reg_ram_m[reg_addr(mode_exec, 13)];
319
assign r14_out = reg_ram_m[reg_addr(mode_exec, 14)];
320
// synthesis translate_on
321
 
322
endmodule
323
 
324
 

powered by: WebSVN 2.1.0

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