3 Copyright (c) 2013, IIT Madras
6 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
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.
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 ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
16 package Memory_vme_32;
18 import defined_types::*;
19 `include "defined_parameters.bsv"
21 `include "vme_parameters.bsv"
23 //typedef enum{Send_req,Get_resp} Mem_state deriving(Bits,Eq);
27 {RCV_REQ,DET_DS,END_REQ
28 }State_slave deriving (Bits,Eq);
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);
44 method Bit#(1) wr_dsack_0_l();
46 method Bit#(1) wr_dsack_1_l();
48 method Bit#(1) wr_berr_l();
50 method Bit#(1) wr_halt_l();
52 //.........Methods to write and read data when tristate is not enabled.........//
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();
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);
65 endinterface:Vme_slave
67 module mkMemory #(parameter String mem_init_file, parameter String module_name) (Vme_slave#(base_address,mem_size));
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);
71 //Defining the slave interface lines
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);
84 Reg#(State_slave) slave_state <- mkReg (RCV_REQ);
87 //..........data_out registers of tristate buffers and their control......
88 //.......................................................................
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);
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
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);
112 rule rcv_req((slave_state==RCV_REQ)&&(start_rd||start_wr));
115 $display("............SELECTING SLAVE WITH PORT WIDTH 32...............");
120 $display("Write_cycle");
127 $display("Starting read from address",$time);
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);
137 1. Checks for data_strobe
138 2. Reads data if data_strobe is asserted
142 rule send_ack(slave_state==DET_DS );
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})
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;
162 case({s_addr[1],s_addr[0]})
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);
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);
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);
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);
186 if({s_addr[1],s_addr[0]}==2'b00)
188 data_out_3<=data0[15:8];
189 data_out_4<=data0[7:0];
190 data_control<=4'b1111;
194 data_out_1<=data0[31:24];
195 data_out_2<=data0[23:16];
196 data_control<=4'b1111;
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})
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});
214 case({s_addr[1],s_addr[0]})
218 dmemLSB.b.put(4'b0001,index_address,{24'b0,data_in_4});
219 $display("Writing data %h",data_in_4);
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});
227 if({s_addr[1],s_addr[0]}==2'b00)
229 dmemLSB.b.put(4'b0011,index_address,{16'b0,data_in_3,data_in_4});
233 dmemLSB.b.put(4'b1100,index_address,{data_in_1,data_in_2,16'b0});
240 //Releases bus if data strobe is released//
241 rule end_req(slave_state==END_REQ);
243 if((s_ds_l==1) &&(s_as_l==1))
249 data_control<=4'b0000;
250 $display("SLAVE_STATE:3 Releasing bus ",$time);
251 slave_state<=RCV_REQ;
258 method Action rd_as_l(Bit#(1) m_as_l);
262 method Action rd_ds_l(Bit#(1)m_ds_l);
266 method Action rd_siz0(Bit#(1)m_ds1_l);
270 method Action rd_siz1(Bit#(1)m_siz1);
274 method Action rd_addr(Bit #(32)m_addr);
279 method Bit#(1) wr_dsack_0_l();
283 method Bit#(1) wr_dsack_1_l();
287 method Bit#(1)wr_berr_l();
291 method Bit#(1)wr_halt_l();
296 method Action rd_wr_l(m_wr_l);
300 /*Methods to emulate tristate functionality*/
303 method Bit#(8) wr_byte_31_24()if(data_control[3]==1);
307 method Bit#(8) wr_byte_23_16()if(data_control[2]==1);
311 method Bit#(8) wr_byte_15_8()if(data_control[1]==1);
316 method Bit#(8) wr_byte_7_0()if (data_control[0]==1);
320 method Action rd_byte_31_24(Bit #(8) d4)if(data_control[3]==0);
324 method Action rd_byte_23_16(Bit #(8) d3)if(data_control[2]==0);
328 method Action rd_byte_15_8 (Bit #(8) d2)if(data_control[1]==0);
332 method Action rd_byte_7_0 (Bit #(8) d1)if(data_control[0]==0);