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 360

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

powered by: WebSVN 2.1.0

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