add peripherals
[shakti-peripherals.git] / src / peripherals / vme / Memory_vme_16.bsv
1 /*
2 Copyright (c) 2013, IIT Madras
3 All rights reserved.
4
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6
7 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
9 * Neither the name of IIT Madras nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
10
11 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
12 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
13 */
14
15 package Memory_vme_16;
16 import defined_types::*;
17 `include "defined_parameters.bsv"
18 import BRAMCore :: *;
19 // import TriState ::*;
20 // import DReg::*;
21 // import Semi_FIFOF :: *;
22 // import AXI4_Types :: *;
23 // import AXI4_Fabric :: *;
24
25
26 typedef enum
27
28 {RCV_REQ,DET_DS,END_REQ
29 }State_slave deriving (Bits,Eq);
30
31 interface Memory_vme_16#(numeric type base_address,numeric type mem_size);
32 (*always_ready, always_enabled*)
33 method Action rd_as_l(Bit#(1) m_as_l);
34 (*always_ready, always_enabled*)
35 method Action rd_ds_l(Bit#(1)m_ds_l);
36 (*always_ready, always_enabled*)
37 method Action rd_siz0(Bit#(1)m_ds1_l);
38 (*always_ready, always_enabled*)
39 method Action rd_siz1(Bit#(1)m_siz1);
40 (*always_ready, always_enabled*)
41 method Action rd_addr(Bit#(32)m_addr);
42 (*always_ready, always_enabled*)
43 method Action rd_wr_l(Bit#(1)m_wr_l);
44 (*always_ready*)
45 method Bit#(1) wr_dsack_0_l();
46 (*always_ready*)
47 method Bit#(1) wr_dsack_1_l();
48 (*always_ready*)
49 method Bit#(1) wr_berr_l();
50 (*always_ready*)
51 method Bit#(1) wr_halt_l();
52
53 //.........Methods to write and read data when tristate is not enabled.........//
54
55
56 method Bit#(8) wr_byte_31_24();
57 method Bit#(8) wr_byte_23_16();
58 //method Bit#(8) wr_byte_15_8();
59 //method Bit#(8) wr_byte_7_0();
60
61 method Action rd_byte_31_24(Bit #(8) d3);
62 method Action rd_byte_23_16(Bit #(8) d2);
63 //method Action rd_byte_15_8 (Bit #(8) d1);
64 //method Action rd_byte_7_0 (Bit #(8) d0);
65
66
67
68 endinterface:Memory_vme_16
69
70 module mkMemory_16 #(parameter String mem_init_file, parameter String module_name) (Memory_vme_16#(base_address,mem_size));
71
72 // `ifdef BRF
73 // BRAM_DUAL_PORT_BE#(Bit#(TSub#(mem_size,2)),Bit#(`Reg_width_vme_slave),TDiv#(`Reg_width_vme_slave,8)) dmemLSB <- mkBRAMCore2BE(valueOf(TExp#(TSub#(mem_size,2))),False);
74 // `else
75 BRAM_DUAL_PORT_BE#(Bit#(TSub#(mem_size,1)),Bit#(16),TDiv#(16,8)) dmemLSB <- mkBRAMCore2BELoad(valueOf(TExp#(TSub#(mem_size,1))),False,mem_init_file,False);
76 // `endif
77
78 //Defining the slave interface lines
79
80 Reg #(Bit#(1)) s_dsack_0_l<-mkReg(1);
81 Reg #(Bit#(1)) s_dsack_1_l<-mkReg(1);
82 Reg #(Bit#(1)) s_berr_l<-mkReg(1);
83 Reg #(Bit#(1)) s_halt_l<-mkReg(1);
84 Wire #(Bit #(1)) s_as_l<-mkDWire(1);
85 Wire #(Bit #(1)) s_ds_l<-mkDWire(1);
86 Wire #(Bit #(1)) s_siz0<-mkDWire(0);
87 Wire #(Bit #(1)) s_siz1<-mkDWire(0);
88 Wire #(Bit #(32)) s_addr<-mkDWire(0);
89 Wire #(Bit #(1)) s_wr_l<-mkDWire(0);
90
91
92 Reg#(State_slave) slave_state <- mkReg (RCV_REQ);
93
94
95 //..........data_out registers of tristate buffers and their control......
96 //.......................................................................
97
98
99 Wire#(Bit#(8)) data_in_4<-mkDWire(0);
100 Wire#(Bit#(8)) data_in_3<-mkDWire(0);
101 //Wire#(Bit#(8)) data_in_2<-mkDWire(0);
102 //Wire#(Bit#(8)) data_in_1<-mkDWire(0);
103
104 Reg#(Bit#(8)) data_out_4<-mkReg(0);
105 Reg#(Bit#(8)) data_out_3<-mkReg(0);
106 //Reg#(Bit#(8)) data_out_2<-mkReg(0);
107 //Reg#(Bit#(8)) data_out_1<-mkReg(0);
108 Reg #(Bit#(2)) data_control <-mkReg(0);
109
110
111 /*In REQ_RCV State_slave
112 1.If read, sends acknowledge on detecting data strobe low
113 puts the data into the data bus
114 2.If write,sends acknowledge on address strobe low
115 */
116
117 Bool start_rd = (s_wr_l==1'b1)&&(s_ds_l==1'b0)&&(s_as_l==1'b0);
118 Bool start_wr = (s_wr_l==1'b0)&&(s_as_l==1'b0);
119 Bool store_data=(s_wr_l==1'b0)&&(s_ds_l==1'b0);
120 rule rcv_req((slave_state==RCV_REQ)&&(start_rd||start_wr));
121
122
123 $display("............SELECTING SLAVE WITH PORT WIDTH 32...............");
124 if(start_wr)
125
126
127 begin
128 $display("Write_cycle");
129 s_dsack_0_l<=1'b1;
130 s_dsack_1_l<=1'b0;
131 slave_state<=DET_DS;
132 end
133 else
134 begin
135 $display("Starting read from address",$time);
136 slave_state<=DET_DS;
137 Bit#(TSub#(mem_size,1)) index_address=(s_addr-fromInteger(valueOf(base_address)))[valueOf(mem_size)-1:1];
138 dmemLSB.b.put(0,index_address,?);
139 $display("Index Address : %h",index_address);
140 end
141
142 endrule
143
144 /*
145 1. Checks for data_strobe
146 2. Reads data if data_strobe is asserted
147 */
148
149
150 rule send_ack(slave_state==DET_DS );
151 if(s_wr_l==1'b1)
152 begin
153 s_dsack_0_l<=1'b1;
154 s_dsack_1_l<=1'b0;
155 slave_state<=END_REQ;
156 Bit#(16) data0 = dmemLSB.b.read();
157 $display("32 bit data_read : %h",data0,$time);
158 case({s_siz1,s_siz0})
159
160 2'b00:
161 begin
162
163 data_out_4 <=data0[7:0];
164 data_out_3 <=data0[15:8];
165 // data_out_2 <=data0[15:8];
166 // data_out_1 <=data0[7:0];
167 data_control<=2'b11;
168 end
169 2'b01 :
170 case({s_addr[1],s_addr[0]})
171 2'b00:begin
172 data_out_4<=data0[7:0];
173 data_control<=2'b11;
174 $display("Reading data %h from %h addr",data0[7:0],s_addr);
175 end
176 2'b01:begin
177 data_out_3<=data0[15:8];
178 data_control<=2'b11;
179 $display("Reading data %h from %h addr",data0[15:8],s_addr);
180 end
181 2'b10:begin
182 data_out_4<=data0[7:0];
183 data_control<=2'b11;
184 $display("Reading data %h from %h addr",data0[7:0],s_addr);
185 end
186 2'b11:begin
187 data_out_3<=data0[15:8];
188 data_control<=2'b11;
189 $display("Reading data %h from %h addr",data0[15:8],s_addr);
190 end
191
192 endcase
193 2'b10 :
194 if({s_addr[1],s_addr[0]}==2'b00)
195 begin
196 data_out_4<=data0[7:0];
197 data_out_3<=data0[15:8];
198 data_control<=2'b11;
199 end
200 else
201 begin
202 data_out_4<=data0[7:0];
203 data_out_3<=data0[15:8];
204 data_control<=2'b11;
205 end
206 endcase
207
208 end
209 else if(store_data)
210
211 begin
212 $display("Writing to addr %0d ",s_addr,$time);
213 slave_state<=END_REQ;
214 Bit#(TSub#(mem_size,1)) index_address=(s_addr-fromInteger(valueOf(base_address)))[valueOf(mem_size)-1:1];
215 $display("Index_address : %h",index_address);
216 case({s_siz1,s_siz0})
217 2'b00 :begin
218 dmemLSB.b.put(2'b11,index_address,{data_in_3,data_in_4});
219 $display ("Data :%0h mode: quad_word",{data_in_3,data_in_4});
220 end
221 2'b01 :begin
222 case({s_addr[1],s_addr[0]})
223 2'b00:
224 begin
225 dmemLSB.b.put(2'b01,index_address,{8'b0,data_in_4});
226 $display("Writing data %h",data_in_4);
227 end
228 2'b01:dmemLSB.b.put(2'b10,index_address,{data_in_3,8'b0});
229 2'b10:dmemLSB.b.put(2'b01,index_address,{8'b0,data_in_4});
230 2'b11:dmemLSB.b.put(2'b10,index_address,{data_in_3,8'b0});
231 endcase
232 end
233 2'b10 :
234 if({s_addr[1],s_addr[0]}==2'b00)
235 begin
236 dmemLSB.b.put(2'b11,index_address,{data_in_3,data_in_4});
237 $display ("Data :%0h mode: double_word",{data_in_3,data_in_4});
238 end
239 else
240 begin
241 dmemLSB.b.put(2'b11,index_address,{data_in_3,data_in_4});
242 $display ("Data :%0h mode: double_word",{data_in_3,data_in_4});
243
244 end
245 endcase
246 end
247 /* if(s_berr_l==1)
248 begin
249 s_dsack_1_l<=s_siz1;
250 s_dsack_0_l<=s_siz0;
251 end
252 // $display("sending ack",$time);
253
254 */
255
256 endrule
257
258 //Releases bus if data strobe is released//
259 rule end_req(slave_state==END_REQ);
260
261 if((s_ds_l==1) &&(s_as_l==1))
262 begin
263 s_dsack_0_l<=1;
264 s_dsack_1_l<=1;
265 s_berr_l<=1;
266 s_halt_l<=1;
267 data_control<=2'b00;
268 $display("SLAVE_STATE:3 Releasing bus ",$time);
269 slave_state<=RCV_REQ;
270 end
271
272 endrule
273
274
275 /*interface s_io_31_24 = d31_24.io;
276 interface s_io_23_16 = d23_16.io;
277 interface s_io_15_8 = d15_8.io;
278 interface s_io_7_0 = d7_0.io;
279 */
280
281 method Action rd_as_l(Bit#(1) m_as_l);
282 s_as_l<=m_as_l;
283 endmethod
284
285 method Action rd_ds_l(Bit#(1)m_ds_l);
286 s_ds_l<=m_ds_l;
287 endmethod
288
289 method Action rd_siz0(Bit#(1)m_ds1_l);
290 s_siz0<=m_ds1_l;
291 endmethod
292
293 method Action rd_siz1(Bit#(1)m_siz1);
294 s_siz1<=m_siz1;
295 endmethod
296
297 method Action rd_addr(Bit #(32)m_addr);
298 s_addr<=m_addr;
299
300 endmethod
301
302 method Bit#(1) wr_dsack_0_l();
303 return s_dsack_0_l;
304 endmethod
305
306 method Bit#(1) wr_dsack_1_l();
307 return s_dsack_1_l;
308 endmethod
309
310 method Bit#(1)wr_berr_l();
311 return s_berr_l;
312 endmethod
313
314 method Bit#(1)wr_halt_l();
315 return s_halt_l;
316 endmethod
317
318
319 method Action rd_wr_l(m_wr_l);
320 s_wr_l<=m_wr_l;
321 endmethod
322
323 /*Methods to emulate tristate functionality*/
324
325
326 method Bit#(8) wr_byte_31_24()if(data_control[1]==1);
327 return data_out_4;
328 endmethod
329
330 method Bit#(8) wr_byte_23_16()if(data_control[0]==1);
331 return data_out_3;
332 endmethod
333
334 /*method Bit#(8) wr_byte_15_8()if(data_control[1]==1);
335 return data_out_2;
336 endmethod
337
338
339 method Bit#(8) wr_byte_7_0()if (data_control[0]==1);
340 return data_out_1;
341 endmethod
342 */
343
344 method Action rd_byte_31_24(Bit #(8) d4)if(data_control[1]==0);
345 data_in_4<=d4;
346 endmethod
347
348 method Action rd_byte_23_16(Bit #(8) d3)if(data_control[0]==0);
349 data_in_3<=d3;
350 endmethod
351
352
353 /*method Action rd_byte_15_8 (Bit #(8) d2)if(data_control[1]==0);
354 data_in_2<=d2;
355 endmethod
356
357 method Action rd_byte_7_0 (Bit #(8) d1)if(data_control[0]==0);
358 data_in_1<=d1;
359 endmethod
360 */
361
362 endmodule
363 endpackage