2 Copyright (c) 2013, IIT Madras
5 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
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.
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 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
15 package Memory_vme_16;
16 import defined_types::*;
17 `include "instance_defines.bsv"
19 // import TriState ::*;
21 // import Semi_FIFOF :: *;
22 // import AXI4_Types :: *;
23 // import AXI4_Fabric :: *;
28 {RCV_REQ,DET_DS,END_REQ
29 }State_slave deriving (Bits,Eq);
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);
45 method Bit#(1) wr_dsack_0_l();
47 method Bit#(1) wr_dsack_1_l();
49 method Bit#(1) wr_berr_l();
51 method Bit#(1) wr_halt_l();
53 //.........Methods to write and read data when tristate is not enabled.........//
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();
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);
68 endinterface:Memory_vme_16
70 module mkMemory_16 #(parameter String mem_init_file, parameter String module_name) (Memory_vme_16#(base_address,mem_size));
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);
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);
78 //Defining the slave interface lines
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);
92 Reg#(State_slave) slave_state <- mkReg (RCV_REQ);
95 //..........data_out registers of tristate buffers and their control......
96 //.......................................................................
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);
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);
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
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));
123 $display("............SELECTING SLAVE WITH PORT WIDTH 32...............");
128 $display("Write_cycle");
135 $display("Starting read from address",$time);
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);
145 1. Checks for data_strobe
146 2. Reads data if data_strobe is asserted
150 rule send_ack(slave_state==DET_DS );
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})
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];
170 case({s_addr[1],s_addr[0]})
172 data_out_4<=data0[7:0];
174 $display("Reading data %h from %h addr",data0[7:0],s_addr);
177 data_out_3<=data0[15:8];
179 $display("Reading data %h from %h addr",data0[15:8],s_addr);
182 data_out_4<=data0[7:0];
184 $display("Reading data %h from %h addr",data0[7:0],s_addr);
187 data_out_3<=data0[15:8];
189 $display("Reading data %h from %h addr",data0[15:8],s_addr);
194 if({s_addr[1],s_addr[0]}==2'b00)
196 data_out_4<=data0[7:0];
197 data_out_3<=data0[15:8];
202 data_out_4<=data0[7:0];
203 data_out_3<=data0[15:8];
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})
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});
222 case({s_addr[1],s_addr[0]})
225 dmemLSB.b.put(2'b01,index_address,{8'b0,data_in_4});
226 $display("Writing data %h",data_in_4);
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});
234 if({s_addr[1],s_addr[0]}==2'b00)
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});
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});
252 // $display("sending ack",$time);
258 //Releases bus if data strobe is released//
259 rule end_req(slave_state==END_REQ);
261 if((s_ds_l==1) &&(s_as_l==1))
268 $display("SLAVE_STATE:3 Releasing bus ",$time);
269 slave_state<=RCV_REQ;
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;
281 method Action rd_as_l(Bit#(1) m_as_l);
285 method Action rd_ds_l(Bit#(1)m_ds_l);
289 method Action rd_siz0(Bit#(1)m_ds1_l);
293 method Action rd_siz1(Bit#(1)m_siz1);
297 method Action rd_addr(Bit #(32)m_addr);
302 method Bit#(1) wr_dsack_0_l();
306 method Bit#(1) wr_dsack_1_l();
310 method Bit#(1)wr_berr_l();
314 method Bit#(1)wr_halt_l();
319 method Action rd_wr_l(m_wr_l);
323 /*Methods to emulate tristate functionality*/
326 method Bit#(8) wr_byte_31_24()if(data_control[1]==1);
330 method Bit#(8) wr_byte_23_16()if(data_control[0]==1);
334 /*method Bit#(8) wr_byte_15_8()if(data_control[1]==1);
339 method Bit#(8) wr_byte_7_0()if (data_control[0]==1);
344 method Action rd_byte_31_24(Bit #(8) d4)if(data_control[1]==0);
348 method Action rd_byte_23_16(Bit #(8) d3)if(data_control[0]==0);
353 /*method Action rd_byte_15_8 (Bit #(8) d2)if(data_control[1]==0);
357 method Action rd_byte_7_0 (Bit #(8) d1)if(data_control[0]==0);