add peripherals
[shakti-peripherals.git] / src / peripherals / vme / Memory_vme_32.bsv
1
2 /*
3 Copyright (c) 2013, IIT Madras
4 All rights reserved.
5
6 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
7
8 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
9 * 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.
10 * 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.
11
12 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.
13 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
14 */
15
16 package Memory_vme_32;
17
18 import defined_types::*;
19 `include "defined_parameters.bsv"
20 import BRAMCore :: *;
21 `include "vme_parameters.bsv"
22
23 //typedef enum{Send_req,Get_resp} Mem_state deriving(Bits,Eq);
24
25 typedef enum
26
27 {RCV_REQ,DET_DS,END_REQ
28 }State_slave deriving (Bits,Eq);
29
30 interface Vme_slave #(numeric type base_address,numeric type mem_size);
31 (*always_ready, always_enabled*)
32 method Action rd_as_l(Bit#(1) m_as_l);
33 (*always_ready, always_enabled*)
34 method Action rd_ds_l(Bit#(1)m_ds_l);
35 (*always_ready, always_enabled*)
36 method Action rd_siz0(Bit#(1)m_ds1_l);
37 (*always_ready, always_enabled*)
38 method Action rd_siz1(Bit#(1)m_siz1);
39 (*always_ready, always_enabled*)
40 method Action rd_addr(Bit#(32)m_addr);
41 (*always_ready, always_enabled*)
42 method Action rd_wr_l(Bit#(1)m_wr_l);
43 (*always_ready*)
44 method Bit#(1) wr_dsack_0_l();
45 (*always_ready*)
46 method Bit#(1) wr_dsack_1_l();
47 (*always_ready*)
48 method Bit#(1) wr_berr_l();
49 (*always_ready*)
50 method Bit#(1) wr_halt_l();
51
52 //.........Methods to write and read data when tristate is not enabled.........//
53
54
55 method Bit#(8) wr_byte_31_24();
56 method Bit#(8) wr_byte_23_16();
57 method Bit#(8) wr_byte_15_8();
58 method Bit#(8) wr_byte_7_0();
59
60 method Action rd_byte_31_24(Bit #(8) d3);
61 method Action rd_byte_23_16(Bit #(8) d2);
62 method Action rd_byte_15_8 (Bit #(8) d1);
63 method Action rd_byte_7_0 (Bit #(8) d0);
64
65 endinterface:Vme_slave
66
67 module mkMemory #(parameter String mem_init_file, parameter String module_name) (Vme_slave#(base_address,mem_size));
68
69 BRAM_DUAL_PORT_BE#(Bit#(TSub#(mem_size,2)),Bit#(`Reg_width_vme_slave),TDiv#(`Reg_width_vme_slave,8)) dmemLSB <- mkBRAMCore2BELoad(valueOf(TExp#(TSub#(mem_size,2))),False,mem_init_file,False);
70
71 //Defining the slave interface lines
72
73 Reg #(Bit#(1)) s_dsack_0_l<-mkReg(1);
74 Reg #(Bit#(1)) s_dsack_1_l<-mkReg(1);
75 Reg #(Bit#(1)) s_berr_l<-mkReg(1);
76 Reg #(Bit#(1)) s_halt_l<-mkReg(1);
77 Wire #(Bit #(1)) s_as_l<-mkDWire(1);
78 Wire #(Bit #(1)) s_ds_l<-mkDWire(1);
79 Wire #(Bit #(1)) s_siz0<-mkDWire(0);
80 Wire #(Bit #(1)) s_siz1<-mkDWire(0);
81 Wire #(Bit #(32)) s_addr<-mkDWire(0);
82 Wire #(Bit #(1)) s_wr_l<-mkDWire(0);
83
84 Reg#(State_slave) slave_state <- mkReg (RCV_REQ);
85
86
87 //..........data_out registers of tristate buffers and their control......
88 //.......................................................................
89
90
91 Wire#(Bit#(8)) data_in_4<-mkDWire(0);
92 Wire#(Bit#(8)) data_in_3<-mkDWire(0);
93 Wire#(Bit#(8)) data_in_2<-mkDWire(0);
94 Wire#(Bit#(8)) data_in_1<-mkDWire(0);
95 Reg#(Bit#(8)) data_out_4<-mkReg(0);
96 Reg#(Bit#(8)) data_out_3<-mkReg(0);
97 Reg#(Bit#(8)) data_out_2<-mkReg(0);
98 Reg#(Bit#(8)) data_out_1<-mkReg(0);
99 Reg #(Bit#(4)) data_control <-mkReg(0);
100
101
102 /*In REQ_RCV State_slave
103 1.If read, sends acknowledge on detecting data strobe low
104 puts the data into the data bus
105 2.If write,sends acknowledge on address strobe low
106 */
107
108 Bool start_rd = (s_wr_l==1'b1)&&(s_ds_l==1'b0)&&(s_as_l==1'b0)&&(s_addr>=32'h40000000 && s_addr<=32'h4FFFFFFF);
109 Bool start_wr = (s_wr_l==1'b0)&&(s_as_l==1'b0)&&(s_addr>=32'h40000000 && s_addr <=32'h4FFFFFFF);
110 Bool store_data=(s_wr_l==1'b0)&&(s_ds_l==1'b0);
111
112 rule rcv_req((slave_state==RCV_REQ)&&(start_rd||start_wr));
113
114
115 $display("............SELECTING SLAVE WITH PORT WIDTH 32...............");
116 if(start_wr)
117
118
119 begin
120 $display("Write_cycle");
121 s_dsack_0_l<=1'b0;
122 s_dsack_1_l<=1'b0;
123 slave_state<=DET_DS;
124 end
125 else
126 begin
127 $display("Starting read from address",$time);
128 slave_state<=DET_DS;
129 Bit#(TSub#(mem_size,2)) index_address=(s_addr-fromInteger(valueOf(base_address)))[valueOf(mem_size)-1:2];
130 dmemLSB.b.put(0,index_address,?);
131 $display("Index Address : %h",index_address);
132 end
133
134 endrule
135
136 /*
137 1. Checks for data_strobe
138 2. Reads data if data_strobe is asserted
139 */
140
141
142 rule send_ack(slave_state==DET_DS );
143 if(s_wr_l==1'b1)
144 begin
145 s_dsack_0_l<=1'b0;
146 s_dsack_1_l<=1'b0;
147 slave_state<=END_REQ;
148 Bit#(`Reg_width_vme_slave) data0 = dmemLSB.b.read();
149 $display("32 bit data_read : %h",data0,$time);
150 case({s_siz1,s_siz0})
151
152 2'b00:
153 begin
154
155 data_out_1 <=data0[31:24];
156 data_out_2 <=data0[23:16];
157 data_out_3 <=data0[15:8];
158 data_out_4 <=data0[7:0];
159 data_control<=4'b1111;
160 end
161 2'b01 :
162 case({s_addr[1],s_addr[0]})
163 2'b00:begin
164 data_out_4<=data0[7:0];
165 data_control<=4'b1111;
166 $display("Reading data %h from %h addr",data0[7:0],s_addr);
167 end
168 2'b01:begin
169 data_out_3<=data0[15:8];
170 data_control<=4'b1111;
171 $display("Reading data %h from %h addr",data0[15:8],s_addr);
172 end
173 2'b10:begin
174 data_out_2<=data0[23:16];
175 data_control<=4'b1111;
176 $display("Reading data %h from %h addr",data0[23:16],s_addr);
177 end
178 2'b11:begin
179 data_out_1<=data0[31:24];
180 data_control<=4'b1111;
181 $display("Reading data %h from %h addr",data0[31:24],s_addr);
182 end
183
184 endcase
185 2'b10 :
186 if({s_addr[1],s_addr[0]}==2'b00)
187 begin
188 data_out_3<=data0[15:8];
189 data_out_4<=data0[7:0];
190 data_control<=4'b1111;
191 end
192 else
193 begin
194 data_out_1<=data0[31:24];
195 data_out_2<=data0[23:16];
196 data_control<=4'b1111;
197 end
198 endcase
199
200 end
201 else if(store_data)
202
203 begin
204 $display("Writing to addr %0d ",s_addr,$time);
205 slave_state<=END_REQ;
206 Bit#(TSub#(mem_size,2)) index_address=(s_addr-fromInteger(valueOf(base_address)))[valueOf(mem_size)-1:2];
207 $display("Index_address : %h",index_address);
208 case({s_siz1,s_siz0})
209 2'b00 :begin
210 dmemLSB.b.put(4'b1111,index_address,{data_in_1,data_in_2,data_in_3,data_in_4});
211 $display ("Data :%0h mode: quad_word",{data_in_1,data_in_2,data_in_3,data_in_4});
212 end
213 2'b01 :begin
214 case({s_addr[1],s_addr[0]})
215 2'b00:begin
216
217
218 dmemLSB.b.put(4'b0001,index_address,{24'b0,data_in_4});
219 $display("Writing data %h",data_in_4);
220 end
221 2'b01:dmemLSB.b.put(4'b0010,index_address,{16'b0,data_in_3,8'b0});
222 2'b10:dmemLSB.b.put(4'b0100,index_address,{8'b0,data_in_2,16'b0});
223 2'b11:dmemLSB.b.put(4'b1000,index_address,{data_in_1,24'b0});
224 endcase
225 end
226 2'b10 :
227 if({s_addr[1],s_addr[0]}==2'b00)
228 begin
229 dmemLSB.b.put(4'b0011,index_address,{16'b0,data_in_3,data_in_4});
230 end
231 else
232 begin
233 dmemLSB.b.put(4'b1100,index_address,{data_in_1,data_in_2,16'b0});
234 end
235 endcase
236 end
237
238 endrule
239
240 //Releases bus if data strobe is released//
241 rule end_req(slave_state==END_REQ);
242
243 if((s_ds_l==1) &&(s_as_l==1))
244 begin
245 s_dsack_0_l<=1;
246 s_dsack_1_l<=1;
247 s_berr_l<=1;
248 s_halt_l<=1;
249 data_control<=4'b0000;
250 $display("SLAVE_STATE:3 Releasing bus ",$time);
251 slave_state<=RCV_REQ;
252 end
253
254 endrule
255
256
257
258 method Action rd_as_l(Bit#(1) m_as_l);
259 s_as_l<=m_as_l;
260 endmethod
261
262 method Action rd_ds_l(Bit#(1)m_ds_l);
263 s_ds_l<=m_ds_l;
264 endmethod
265
266 method Action rd_siz0(Bit#(1)m_ds1_l);
267 s_siz0<=m_ds1_l;
268 endmethod
269
270 method Action rd_siz1(Bit#(1)m_siz1);
271 s_siz1<=m_siz1;
272 endmethod
273
274 method Action rd_addr(Bit #(32)m_addr);
275 s_addr<=m_addr;
276
277 endmethod
278
279 method Bit#(1) wr_dsack_0_l();
280 return s_dsack_0_l;
281 endmethod
282
283 method Bit#(1) wr_dsack_1_l();
284 return s_dsack_1_l;
285 endmethod
286
287 method Bit#(1)wr_berr_l();
288 return s_berr_l;
289 endmethod
290
291 method Bit#(1)wr_halt_l();
292 return s_halt_l;
293 endmethod
294
295
296 method Action rd_wr_l(m_wr_l);
297 s_wr_l<=m_wr_l;
298 endmethod
299
300 /*Methods to emulate tristate functionality*/
301
302
303 method Bit#(8) wr_byte_31_24()if(data_control[3]==1);
304 return data_out_4;
305 endmethod
306
307 method Bit#(8) wr_byte_23_16()if(data_control[2]==1);
308 return data_out_3;
309 endmethod
310
311 method Bit#(8) wr_byte_15_8()if(data_control[1]==1);
312 return data_out_2;
313 endmethod
314
315
316 method Bit#(8) wr_byte_7_0()if (data_control[0]==1);
317 return data_out_1;
318 endmethod
319
320 method Action rd_byte_31_24(Bit #(8) d4)if(data_control[3]==0);
321 data_in_4<=d4;
322 endmethod
323
324 method Action rd_byte_23_16(Bit #(8) d3)if(data_control[2]==0);
325 data_in_3<=d3;
326 endmethod
327
328 method Action rd_byte_15_8 (Bit #(8) d2)if(data_control[1]==0);
329 data_in_2<=d2;
330 endmethod
331
332 method Action rd_byte_7_0 (Bit #(8) d1)if(data_control[0]==0);
333 data_in_1<=d1;
334 endmethod
335
336
337 endmodule
338 endpackage