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 682

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

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

powered by: WebSVN 2.1.0

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