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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [rtl/] [verilog/] [wb_ram_b3/] [wb_ram_b3.v] - Blame information for rev 590

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

Line No. Rev Author Line
1 351 julius
 
2
// Version 5
3
 
4
//`define RANDOM_ACK_NEGATION
5
 
6
module wb_ram_b3(
7
                 wb_adr_i, wb_bte_i, wb_cti_i, wb_cyc_i, wb_dat_i, wb_sel_i,
8
                 wb_stb_i, wb_we_i,
9
 
10
                 wb_ack_o, wb_err_o, wb_rty_o, wb_dat_o,
11
 
12
                 wb_clk_i, wb_rst_i);
13
 
14
   // Memory parameters
15
   parameter dw = 32;
16
 
17
   // 32MB memory by default
18 363 julius
   parameter aw = 23;
19 351 julius
   parameter mem_size  = 8388608;
20
 
21
   input [aw-1:0]        wb_adr_i;
22
   input [1:0]           wb_bte_i;
23
   input [2:0]           wb_cti_i;
24
   input                wb_cyc_i;
25
   input [dw-1:0]        wb_dat_i;
26
   input [3:0]           wb_sel_i;
27
   input                wb_stb_i;
28
   input                wb_we_i;
29
 
30
   output               wb_ack_o;
31
   output               wb_err_o;
32
   output               wb_rty_o;
33
   output [dw-1:0]       wb_dat_o;
34
 
35
   input                wb_clk_i;
36
   input                wb_rst_i;
37
 
38
 
39
   // synthesis attribute ram_style of mem is block
40
   reg [dw-1:0]  mem [ 0 : mem_size-1 ]  /* verilator public */ /* synthesis ram_style = no_rw_check */;
41
 
42
   //reg [aw-1:2] wb_adr_i_r;
43 363 julius
   reg [aw-1:0] adr;
44 351 julius
 
45
   wire [31:0]                      wr_data;
46
 
47
   // Register to indicate if the cycle is a Wishbone B3-registered feedback 
48
   // type access
49
   reg                             wb_b3_trans;
50
   wire                            wb_b3_trans_start, wb_b3_trans_stop;
51
 
52
   // Register to use for counting the addresses when doing burst accesses
53 363 julius
   reg [aw-1:0]  burst_adr_counter;
54 351 julius
   reg [2:0]                        wb_cti_i_r;
55
   reg [1:0]                        wb_bte_i_r;
56
   wire                            using_burst_adr;
57
   wire                            burst_access_wrong_wb_adr;
58
 
59
   reg                             random_ack_negate;
60
 
61
   // Logic to detect if there's a burst access going on
62
   assign wb_b3_trans_start = ((wb_cti_i == 3'b001)|(wb_cti_i == 3'b010)) &
63
                              wb_stb_i & !wb_b3_trans;
64
 
65
   assign  wb_b3_trans_stop = (wb_cti_i == 3'b111) &
66
                              wb_stb_i & wb_b3_trans & wb_ack_o;
67
 
68
   always @(posedge wb_clk_i)
69
     if (wb_rst_i)
70
       wb_b3_trans <= 0;
71
     else if (wb_b3_trans_start)
72
       wb_b3_trans <= 1;
73
     else if (wb_b3_trans_stop)
74
       wb_b3_trans <= 0;
75
 
76
   // Burst address generation logic
77 353 julius
   always @*
78 351 julius
     if (wb_rst_i)
79 353 julius
       burst_adr_counter = 0;
80 351 julius
     else if (wb_b3_trans_start)
81 363 julius
       burst_adr_counter = {2'b00,wb_adr_i[aw-1:2]};
82 351 julius
     else if ((wb_cti_i_r == 3'b010) & wb_ack_o & wb_b3_trans)
83
       // Incrementing burst
84
       begin
85
          if (wb_bte_i_r == 2'b00) // Linear burst
86 353 julius
            burst_adr_counter = adr + 1;
87 351 julius
          if (wb_bte_i_r == 2'b01) // 4-beat wrap burst
88 353 julius
            burst_adr_counter[1:0] = adr[1:0] + 1;
89 351 julius
          if (wb_bte_i_r == 2'b10) // 8-beat wrap burst
90 353 julius
            burst_adr_counter[2:0] = adr[2:0] + 1;
91 351 julius
          if (wb_bte_i_r == 2'b11) // 16-beat wrap burst
92 353 julius
            burst_adr_counter[3:0] = adr[3:0] + 1;
93 351 julius
       end // if ((wb_cti_i_r == 3'b010) & wb_ack_o_r)
94
     else if (!wb_ack_o & wb_b3_trans)
95 353 julius
            burst_adr_counter = adr;
96 351 julius
 
97
 
98
   always @(posedge wb_clk_i)
99
     wb_bte_i_r <= wb_bte_i;
100
 
101
   // Register it locally
102
   always @(posedge wb_clk_i)
103
     wb_cti_i_r <= wb_cti_i;
104
 
105
   assign using_burst_adr = wb_b3_trans;
106
 
107 363 julius
   assign burst_access_wrong_wb_adr = (using_burst_adr & (adr != {2'b00,wb_adr_i[aw-1:2]}));
108 351 julius
 
109
   // Address registering logic
110
   always@(posedge wb_clk_i)
111
     if(wb_rst_i)
112
       adr <= 0;
113
     else if (using_burst_adr)
114
       adr <= burst_adr_counter;
115
     else if (wb_cyc_i & wb_stb_i)
116 363 julius
       adr <= {2'b00,wb_adr_i[aw-1:2]};
117 351 julius
 
118
   parameter memory_file = "sram.vmem";
119
 
120
 
121
`ifdef verilator
122
 
123
   task do_readmemh;
124
      // verilator public
125
      $readmemh(memory_file, mem);
126
   endtask // do_readmemh
127
 
128
`else
129
 
130
   initial
131
     begin
132
        $readmemh(memory_file, mem);
133
     end
134
 
135
`endif // !`ifdef verilator
136
 
137
 
138
   // Function to access RAM (for use by Verilator).
139
   function [31:0] get_mem;
140
      // verilator public
141
      input [aw-1:0]             addr;
142
      get_mem = mem[addr];
143
   endfunction // get_mem
144
 
145
   // Function to write RAM (for use by Verilator).
146
   function set_mem;
147
      // verilator public
148
      input [aw-1:0]             addr;
149
      input [dw-1:0]             data;
150
      mem[addr] = data;
151
   endfunction // set_mem
152
 
153
 
154
   assign wb_rty_o = 0;
155
 
156
   // mux for data to ram, RMW on part sel != 4'hf
157
   assign wr_data[31:24] = wb_sel_i[3] ? wb_dat_i[31:24] : wb_dat_o[31:24];
158
   assign wr_data[23:16] = wb_sel_i[2] ? wb_dat_i[23:16] : wb_dat_o[23:16];
159
   assign wr_data[15: 8] = wb_sel_i[1] ? wb_dat_i[15: 8] : wb_dat_o[15: 8];
160
   assign wr_data[ 7: 0] = wb_sel_i[0] ? wb_dat_i[ 7: 0] : wb_dat_o[ 7: 0];
161
 
162
   // Address logic
163
   /*
164
   always @(posedge wb_clk_i)
165
     begin
166
        if (wb_rst_i)
167
          wb_adr_i_r <= 0;
168
        else
169
          if (wb_cyc_i & wb_stb_i)
170
            wb_adr_i_r <= wb_adr_i[aw-1:2];
171
     end
172
    */
173
 
174
   wire ram_we;
175
   assign ram_we = wb_we_i & wb_ack_o;
176
 
177
   assign wb_dat_o = mem[adr];
178
 
179
   // Write logic
180
   always @ (posedge wb_clk_i)
181
     begin
182
        if (ram_we)
183
          mem[adr] <= wr_data;
184
     end
185
 
186
   // Ack Logic
187
   reg wb_ack_o_r;
188
 
189
   assign wb_ack_o = wb_ack_o_r & wb_stb_i;
190
 
191 353 julius
   always @(posedge wb_clk_i)
192 351 julius
     if (wb_rst_i)
193
       begin
194
          wb_ack_o_r <= 1'b0;
195
       end
196
     else if (wb_cyc_i) // We have bus
197
       begin
198
          if (wb_cti_i == 3'b111)
199
            begin
200
               // End of burst
201
               if (wb_ack_o_r)
202
                 // ALWAYS de-assert ack after burst end
203
                 wb_ack_o_r <= 0;
204
               else if (wb_stb_i & !random_ack_negate)
205
                 wb_ack_o_r <= 1;
206
               else
207
                 wb_ack_o_r <= 0;
208
            end
209
          else if (wb_cti_i == 3'b000)
210
            begin
211
               // Classic cycle acks
212
               if (wb_stb_i & !random_ack_negate)
213
                 begin
214
                    if (!wb_ack_o_r)
215
                      wb_ack_o_r <= 1;
216
                    else
217
                      wb_ack_o_r <= 0;
218
                 end
219
               else
220
                 wb_ack_o_r <= 0;
221
            end // if (wb_cti_i == 3'b000)
222
          else if ((wb_cti_i == 3'b001) | (wb_cti_i == 3'b010))
223
            begin
224
               // Increment/constant address bursts
225
               if (wb_stb_i & !random_ack_negate)
226
                 wb_ack_o_r <= 1;
227
               else
228
                 wb_ack_o_r <= 0;
229
            end
230
          else if (wb_cti_i == 3'b111)
231
            begin
232
               // End of cycle
233
               if (wb_stb_i & !random_ack_negate)
234
                 wb_ack_o_r <= 1;
235
               else
236
                 wb_ack_o_r <= 0;
237
            end
238
       end // if (wb_cyc_i)
239
     else
240
       wb_ack_o_r <= 0;
241
 
242
   assign wb_err_o = 1'b0;// wb_ack_o & (burst_access_wrong_wb_adr); // OR in other errors here
243
 
244
 
245
   // Random ACK negation logic
246
`ifdef RANDOM_ACK_NEGATION
247
   reg [31:0] lfsr;
248
   always @(posedge wb_clk_i)
249
     if (wb_rst_i)
250
       lfsr <= 32'h273e2d4a;
251
     else lfsr <= {lfsr[30:0], ~(lfsr[30]^lfsr[6]^lfsr[4]^lfsr[1]^lfsr[0])};
252
 
253
   always @(posedge wb_clk_i)
254
     random_ack_negate <= lfsr[26];
255
 
256
`else
257
   always @(wb_rst_i)
258 353 julius
     random_ack_negate = 0;
259 351 julius
`endif
260
 
261
 
262
 
263
endmodule // wb_ram_b3_v2
264
 

powered by: WebSVN 2.1.0

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