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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [orpsocv2/] [rtl/] [verilog/] [ram_wb/] [ram_wb_b3.v] - Blame information for rev 439

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

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

powered by: WebSVN 2.1.0

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