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

Subversion Repositories soc_maker

[/] [soc_maker/] [trunk/] [core_lib/] [cores/] [ram_wb/] [ram_wb_b3.v.in] - Blame information for rev 8

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 8 feddischso
//`include "synthesis-defines.v"
2
module ram_wb_b3(
3
                 wb_adr_i, wb_bte_i, wb_cti_i, wb_cyc_i, wb_dat_i, wb_sel_i,
4
                 wb_stb_i, wb_we_i,
5
 
6
                 wb_ack_o, wb_err_o, wb_rty_o, wb_dat_o,
7
 
8
                 wb_clk_i, wb_rst_i);
9
 
10
   parameter dw = 32;
11
   parameter aw = 32;
12
 
13
   input [aw-1:0]       wb_adr_i;
14
   input [1:0]          wb_bte_i;
15
   input [2:0]          wb_cti_i;
16
   input                wb_cyc_i;
17
   input [dw-1:0]       wb_dat_i;
18
   input [3:0]          wb_sel_i;
19
   input                wb_stb_i;
20
   input                wb_we_i;
21
 
22
   output               wb_ack_o;
23
   output               wb_err_o;
24
   output               wb_rty_o;
25
   output [dw-1:0]      wb_dat_o;
26
 
27
   input                wb_clk_i;
28
   input                wb_rst_i;
29
 
30
   // Memory parameters
31
// parameter mem_size_bytes = 32'h0000_5000; // 20KBytes
32
// parameter mem_adr_width = 15; //(log2(mem_size_bytes));
33
   parameter mem_size_kbytes = TOK_MEM_SIZE ; // 20KBytes
34
   parameter mem_adr_width = TOK_MEM_ADR_WIDTH ; //(log2(mem_size_bytes));
35
 
36
   parameter bytes_per_dw = (dw/8);
37
   parameter adr_width_for_num_word_bytes = 2; //(log2(bytes_per_dw))
38
   parameter mem_words = (mem_size_kbytes * 1024/bytes_per_dw);
39
 
40
   // synthesis attribute ram_style of mem is block
41
   reg [dw-1:0]         mem [ 0 : mem_words-1 ]   /* verilator public */ /* synthesis ram_style = no_rw_check */;
42
 
43
   // Register to address internal memory array
44
   reg [(mem_adr_width-adr_width_for_num_word_bytes)-1:0] adr;
45
 
46
   wire [31:0]                     wr_data;
47
 
48
   // Register to indicate if the cycle is a Wishbone B3-registered feedback
49
   // type access
50
   reg                             wb_b3_trans;
51
   wire                            wb_b3_trans_start, wb_b3_trans_stop;
52
 
53
   // Register to use for counting the addresses when doing burst accesses
54
   reg [mem_adr_width-adr_width_for_num_word_bytes-1:0]  burst_adr_counter;
55
   reg [2:0]                       wb_cti_i_r;
56
   reg [1:0]                       wb_bte_i_r;
57
   wire                            using_burst_adr;
58
   wire                            burst_access_wrong_wb_adr;
59
 
60
   // Wire to indicate addressing error
61
   wire                            addr_err;
62
 
63
 
64
   // Logic to detect if there's a burst access going on
65
   assign wb_b3_trans_start = ((wb_cti_i == 3'b001)|(wb_cti_i == 3'b010)) &
66
                              wb_stb_i & !wb_b3_trans;
67
 
68
   assign  wb_b3_trans_stop = ((wb_cti_i == 3'b111) &
69
                              wb_stb_i & wb_b3_trans & wb_ack_o) | wb_err_o;
70
 
71
   always @(posedge wb_clk_i)
72
     if (wb_rst_i)
73
       wb_b3_trans <= 0;
74
     else if (wb_b3_trans_start)
75
       wb_b3_trans <= 1;
76
     else if (wb_b3_trans_stop)
77
       wb_b3_trans <= 0;
78
 
79
   // Burst address generation logic
80
   always @(/*AUTOSENSE*/wb_ack_o or wb_b3_trans or wb_b3_trans_start
81
            or wb_bte_i_r or wb_cti_i_r or wb_adr_i or adr)
82
     if (wb_b3_trans_start)
83
       // Kick off burst_adr_counter, this assumes 4-byte words when getting
84
       // address off incoming Wishbone bus address!
85
       // So if dw is no longer 4 bytes, change this!
86
       burst_adr_counter = wb_adr_i[mem_adr_width-1:2];
87
     else if ((wb_cti_i_r == 3'b010) & wb_ack_o & wb_b3_trans)
88
       // Incrementing burst
89
       begin
90
          if (wb_bte_i_r == 2'b00) // Linear burst
91
            burst_adr_counter = adr + 1;
92
          if (wb_bte_i_r == 2'b01) // 4-beat wrap burst
93
            burst_adr_counter[1:0] = adr[1:0] + 1;
94
          if (wb_bte_i_r == 2'b10) // 8-beat wrap burst
95
            burst_adr_counter[2:0] = adr[2:0] + 1;
96
          if (wb_bte_i_r == 2'b11) // 16-beat wrap burst
97
            burst_adr_counter[3:0] = adr[3:0] + 1;
98
       end // if ((wb_cti_i_r == 3'b010) & wb_ack_o_r)
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 &
110
                                       (adr != wb_adr_i[mem_adr_width-1:2]));
111
 
112
   // Address registering logic
113
   always@(posedge wb_clk_i)
114
     if(wb_rst_i)
115
       adr <= 0;
116
     else if (using_burst_adr)
117
       adr <= burst_adr_counter;
118
     else if (wb_cyc_i & wb_stb_i)
119
       adr <= wb_adr_i[mem_adr_width-1:2];
120
 
121
   /* Memory initialisation.
122
    If not Verilator model, always do load, otherwise only load when called
123
    from SystemC testbench.
124
    */
125
// synthesis translate_off
126
   parameter memory_file = "sram.vmem";
127
 
128
`ifdef verilator
129
 
130
   task do_readmemh;
131
      // verilator public
132
      $readmemh(memory_file, mem);
133
   endtask // do_readmemh
134
 
135
`else
136
 
137
   initial
138
     begin
139
        $readmemh(memory_file, mem);
140
     end
141
 
142
`endif // !`ifdef verilator
143
 
144
//synthesis translate_on
145
 
146
   assign wb_rty_o = 0;
147
 
148
   // mux for data to ram, RMW on part sel != 4'hf
149
   assign wr_data[31:24] = wb_sel_i[3] ? wb_dat_i[31:24] : wb_dat_o[31:24];
150
   assign wr_data[23:16] = wb_sel_i[2] ? wb_dat_i[23:16] : wb_dat_o[23:16];
151
   assign wr_data[15: 8] = wb_sel_i[1] ? wb_dat_i[15: 8] : wb_dat_o[15: 8];
152
   assign wr_data[ 7: 0] = wb_sel_i[0] ? wb_dat_i[ 7: 0] : wb_dat_o[ 7: 0];
153
 
154
   wire ram_we;
155
   assign ram_we = wb_we_i & wb_ack_o;
156
 
157
   assign wb_dat_o = mem[adr];
158
 
159
   // Write logic
160
   always @ (posedge wb_clk_i)
161
     begin
162
        if (ram_we)
163
          mem[adr] <= wr_data;
164
     end
165
 
166
   // Ack Logic
167
   reg wb_ack_o_r;
168
 
169
   assign wb_ack_o = wb_ack_o_r & wb_stb_i &
170
                     !(burst_access_wrong_wb_adr | addr_err);
171
 
172
   always @ (posedge wb_clk_i)
173
     if (wb_rst_i)
174
       wb_ack_o_r <= 1'b0;
175
     else if (wb_cyc_i) // We have bus
176
       begin
177
          if (addr_err & wb_stb_i)
178
            begin
179
               wb_ack_o_r <= 1;
180
            end
181
          else if (wb_cti_i == 3'b000)
182
            begin
183
               // Classic cycle acks
184
               if (wb_stb_i)
185
                 begin
186
                    if (!wb_ack_o_r)
187
                      wb_ack_o_r <= 1;
188
                    else
189
                      wb_ack_o_r <= 0;
190
                 end
191
            end // if (wb_cti_i == 3'b000)
192
          else if ((wb_cti_i == 3'b001) | (wb_cti_i == 3'b010))
193
            begin
194
               // Increment/constant address bursts
195
               if (wb_stb_i)
196
                 wb_ack_o_r <= 1;
197
               else
198
                 wb_ack_o_r <= 0;
199
            end
200
          else if (wb_cti_i == 3'b111)
201
            begin
202
               // End of cycle
203
               if (!wb_ack_o_r)
204
                 wb_ack_o_r <= wb_stb_i;
205
               else
206
                 wb_ack_o_r <= 0;
207
            end
208
       end // if (wb_cyc_i)
209
     else
210
       wb_ack_o_r <= 0;
211
 
212
 
213
   //
214
   // Error signal generation
215
   //
216
 
217
   // Error when out of bounds of memory - skip top nibble of address in case
218
   // this is mapped somewhere other than 0x0.
219
   assign addr_err  = wb_cyc_i & wb_stb_i & (|wb_adr_i[aw-1-4:mem_adr_width]);
220
 
221
   // OR in other errors here...
222
   assign wb_err_o =  wb_ack_o_r & wb_stb_i &
223
                      (burst_access_wrong_wb_adr | addr_err);
224
 
225
   //
226
   // Access functions
227
   //
228
 
229
   // Function to access RAM (for use by Verilator).
230
   function [31:0] get_mem32;
231
      // verilator public
232
      input [aw-1:0]            addr;
233
      get_mem32 = mem[addr];
234
   endfunction // get_mem32
235
 
236
   // Function to access RAM (for use by Verilator).
237
   function [7:0] get_mem8;
238
      // verilator public
239
      input [aw-1:0]            addr;
240
            reg [31:0]          temp_word;
241
      begin
242
         temp_word = mem[{addr[aw-1:2],2'd0}];
243
         // Big endian mapping.
244
         get_mem8 = (addr[1:0]==2'b00) ? temp_word[31:24] :
245
                    (addr[1:0]==2'b01) ? temp_word[23:16] :
246
                    (addr[1:0]==2'b10) ? temp_word[15:8] : temp_word[7:0];
247
         end
248
   endfunction // get_mem8
249
 
250
   // Function to write RAM (for use by Verilator).
251
   function set_mem32;
252
      // verilator public
253
      input [aw-1:0]            addr;
254
      input [dw-1:0]            data;
255
      mem[addr] = data;
256
   endfunction // set_mem32
257
 
258
endmodule // ram_wb_b3
259
 

powered by: WebSVN 2.1.0

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