--- /dev/null
+/*
+Copyright (c) 2013, IIT Madras
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+* 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.
+* 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.
+
+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.
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+*/
+package AXI4Lite_AXI4_Bridge;
+ /*=== Project imports ====*/
+ import AXI4_Lite_Fabric::*;
+ import AXI4_Lite_Types::*;
+ import AXI4_Fabric::*;
+ import AXI4_Types ::*;
+ import Semi_FIFOF ::*;
+ import defined_types::*;
+ import axi_addr_generator::*;
+ `include "instance_defines.bsv"
+ /*======================*/
+ /*=== Package imports ===*/
+ import Clocks::*;
+ /*=======================*/
+
+ interface Ifc_AXI4Lite_AXI4_Bridge;
+ interface AXI4_Slave_IFC#(`PADDR,`Reg_width,`USERSPACE) axi_slave;
+ interface AXI4_Lite_Master_IFC#(`PADDR,64,`USERSPACE) axi4_lite_master;
+ endinterface
+
+ typedef enum {RegularReq,BurstReq} BridgeState deriving (Bits,Eq,FShow);
+
+ (*synthesize*)
+ module mkAXI4Lite_AXI4_Bridge#(Clock fast_clock, Reset fast_reset)(Ifc_AXI4Lite_AXI4_Bridge);
+ AXI4_Slave_Xactor_IFC #(`PADDR, `Reg_width, `USERSPACE) s_xactor <- mkAXI4_Slave_Xactor(clocked_by fast_clock, reset_by fast_reset);
+ AXI4_Lite_Master_Xactor_IFC #(`PADDR,`Reg_width,`USERSPACE) m_xactor <- mkAXI4_Lite_Master_Xactor;
+ Reg#(BridgeState) rd_state <-mkReg(RegularReq,clocked_by fast_clock, reset_by fast_reset);
+ Reg#(BridgeState) wr_state <-mkReg(RegularReq,clocked_by fast_clock, reset_by fast_reset);
+ Reg#(Bit#(4)) rd_id<-mkReg(0);
+ Reg#(Bit#(4)) wr_id<-mkReg(0);
+ Reg#(Bit#(8)) request_counter<-mkReg(0,clocked_by fast_clock, reset_by fast_reset);
+ Reg#(Bit#(8)) rd_response_counter<-mkReg(0);
+ Reg#(Bit#(8)) wr_response_counter <- mkReg(0);
+ Reg#(Bit#(8)) sync_rdburst_value <-mkSyncRegToCC(0,fast_clock,fast_reset);
+ Reg#(Bit#(8)) sync_wrburst_value <-mkSyncRegToCC(0,fast_clock,fast_reset);
+ Reg#(AXI4_Rd_Addr #(`PADDR,`USERSPACE)) rg_read_packet <-mkReg(?,clocked_by fast_clock , reset_by fast_reset);
+ Reg#(AXI4_Wr_Addr #(`PADDR,`USERSPACE)) rg_write_packet<-mkReg(?,clocked_by fast_clock , reset_by fast_reset);
+
+ /*=== FIFOs to synchronize data between the two clock domains ====*/
+ SyncFIFOIfc#(AXI4_Rd_Addr #(`PADDR,`USERSPACE)) ff_rd_addr <- mkSyncFIFOToCC(1,fast_clock,fast_reset);
+ SyncFIFOIfc#(AXI4_Wr_Addr #(`PADDR, `USERSPACE)) ff_wr_addr <- mkSyncFIFOToCC(1,fast_clock,fast_reset);
+ SyncFIFOIfc#(AXI4_Wr_Data #(`Reg_width)) ff_wr_data <- mkSyncFIFOToCC(1,fast_clock,fast_reset);
+
+ SyncFIFOIfc#(AXI4_Rd_Data #(`Reg_width,`USERSPACE)) ff_rd_resp <- mkSyncFIFOFromCC(1,fast_clock);
+ SyncFIFOIfc#(AXI4_Wr_Resp #(`USERSPACE)) ff_wr_resp <- mkSyncFIFOFromCC(1,fast_clock);
+ /*=================================================================*/
+
+
+ // These rule will receive the read request from the AXI4 fabric and pass it on to the AXI4Lite fabric.
+ // If the request is a burst then they are broken down to individual axi4lite read requests. These
+ // are carried out in the next rule.
+ rule capture_read_requests_from_Axi4(rd_state==RegularReq);
+ let request<-pop_o(s_xactor.o_rd_addr);
+ ff_rd_addr.enq(request);
+ rg_read_packet<=request;
+ sync_rdburst_value<=request.arlen;
+ if(request.arlen!=0) begin
+ rd_state<=BurstReq;
+ end
+ endrule
+ // In case a read-burst request is received on the fast bus, then the bursts have to broken down into
+ // individual slow-bus read requests.
+ // This is rule is fired after the first read-burst request is sent to the slow_bus. This rule will continue to
+ // fire as long as the slow bus has capacity to receive a new request and the burst is not complete.
+ // the difference between the each individual requests on the slow bus is only the address. All other
+ // parameters remain the same.
+ rule generate_bust_read_requests(rd_state==BurstReq);
+ let request=rg_read_packet;
+ request.araddr=burst_address_generator(request.arlen, request.arsize, request.arburst,request.araddr);
+ rg_read_packet<=request;
+ ff_rd_addr.enq(request);
+ if(request.arlen==request_counter)begin
+ rd_state<=RegularReq;
+ request_counter<=0;
+ end
+ else
+ request_counter<=request_counter+1;
+ endrule
+ rule send_read_request_on_slow_bus;
+ let request=ff_rd_addr.first;
+ ff_rd_addr.deq;
+ let lite_request = AXI4_Lite_Rd_Addr {araddr: request.araddr, arsize:request.arsize,aruser: 0}; // arburst: 00-FIXED 01-INCR 10-WRAP
+ m_xactor.i_rd_addr.enq(lite_request);
+ rd_id<=request.arid;
+ endrule
+ // This rule will capture the write request from the AXI4 fabric and pass it on to the AXI4Lite fabric.
+ // In case of burst requests, they are broken down to individual requests of axi4lite writes. Care
+ // needs to be taken when writes are of different sizes in settin the write-strobe correctly.
+ rule capture_write_requests_from_Axi4(wr_state==RegularReq);
+ let wr_addr_req <- pop_o (s_xactor.o_wr_addr);
+ let wr_data_req <- pop_o (s_xactor.o_wr_data);
+ ff_wr_addr.enq(wr_addr_req);
+ ff_wr_data.enq(wr_data_req);
+ rg_write_packet<=wr_addr_req;
+ sync_wrburst_value <= wr_addr_req.awlen;
+ if(wr_addr_req.awlen!=0) begin
+ wr_state<=BurstReq;
+ end
+ `ifdef verbose $display($time,"\tAXIBRIDGE: Write Request"); `endif
+ `ifdef verbose $display($time,"\tAddress Channel :",fshow(wr_addr_req)); `endif
+ `ifdef verbose $display($time,"\tData Channel :",fshow(wr_data_req)); `endif
+ endrule
+ // In case a write-burst request is received on the fast bus, then the bursts have to broken down into
+ // individual slow-bus write requests.
+ // This is rule is fired after the first write-burst request is sent to the slow_bus. This rule will continue to
+ // fire as long as the slow bus has capacity to receive a new request and the burst is not complete i.e.
+ // fast bust xactor does not send wlast asserted.
+ // The difference between the each individual requests on the slow bus is only the address. All other
+ // parameters remain the same.
+ rule generate_bust_write_requests(wr_state==BurstReq);
+ let request=rg_write_packet;
+ request.awaddr=burst_address_generator(request.awlen, request.awsize, request.awburst,request.awaddr);
+ let wr_data_req <- pop_o (s_xactor.o_wr_data);
+ ff_wr_addr.enq(request);
+ ff_wr_data.enq(wr_data_req);
+ rg_write_packet<=request;
+ if(wr_data_req.wlast)begin
+ wr_state<=RegularReq;
+ end
+ `ifdef verbose $display($time,"\tAXIBRIDGE: Burst Write Request"); `endif
+ `ifdef verbose $display($time,"\tAddress Channel :",fshow(rg_write_packet)); `endif
+ `ifdef verbose $display($time,"\tData Channel :",fshow(wr_data_req)); `endif
+ endrule
+ rule send_write_request_on_slow_bus;
+ let wr_addr_req = ff_wr_addr.first;
+ let wr_data_req = ff_wr_data.first;
+ ff_wr_data.deq;
+ ff_wr_addr.deq;
+ let aw = AXI4_Lite_Wr_Addr {awaddr: wr_addr_req.awaddr, awuser:0, awsize: wr_addr_req.awsize}; // arburst: 00-FIXED 01-INCR 10-WRAP
+ let w = AXI4_Lite_Wr_Data {wdata: wr_data_req.wdata, wstrb: wr_data_req.wstrb};
+ m_xactor.i_wr_addr.enq(aw);
+ m_xactor.i_wr_data.enq(w);
+ wr_id<=wr_addr_req.awid;
+ endrule
+
+ // This rule forwards the read response from the AXI4Lite to the AXI4 fabric.
+ rule capture_read_responses;
+ let response <- pop_o (m_xactor.o_rd_data);
+ AXI4_Resp rresp= case(response.rresp)
+ AXI4_LITE_OKAY : AXI4_OKAY;
+ AXI4_LITE_EXOKAY: AXI4_EXOKAY;
+ AXI4_LITE_SLVERR: AXI4_SLVERR;
+ AXI4_LITE_DECERR: AXI4_DECERR;
+ default: AXI4_SLVERR; endcase;
+ AXI4_Rd_Data#(`Reg_width,0) r = AXI4_Rd_Data {rresp: rresp, rdata: response.rdata ,rlast:rd_response_counter==sync_rdburst_value, ruser: 0, rid:rd_id};
+ if(rd_response_counter==sync_rdburst_value)
+ rd_response_counter<=0;
+ else
+ rd_response_counter<=rd_response_counter+1;
+ ff_rd_resp.enq(r);
+ endrule
+ rule send_read_response_on_fast_bus;
+ ff_rd_resp.deq;
+ s_xactor.i_rd_data.enq(ff_rd_resp.first);
+ endrule
+ rule capture_write_responses;
+ let response<-pop_o(m_xactor.o_wr_resp);
+ AXI4_Resp bresp= case(response.bresp)
+ AXI4_LITE_OKAY : AXI4_OKAY;
+ AXI4_LITE_EXOKAY: AXI4_EXOKAY;
+ AXI4_LITE_SLVERR: AXI4_SLVERR;
+ AXI4_LITE_DECERR: AXI4_DECERR;
+ default: AXI4_SLVERR; endcase;
+ let b = AXI4_Wr_Resp {bresp: bresp, buser:0, bid:wr_id};
+ if(wr_response_counter == sync_wrburst_value) begin
+ ff_wr_resp.enq(b);
+ wr_response_counter <= 0;
+ end
+ else
+ wr_response_counter <= wr_response_counter + 1;
+ endrule
+ rule send_write_response_on_fast_bus;
+ ff_wr_resp.deq;
+ s_xactor.i_wr_resp.enq(ff_wr_resp.first);
+ endrule
+ interface axi_slave=s_xactor.axi_side;
+ interface axi4_lite_master=m_xactor.axi_side;
+ endmodule
+endpackage
--- /dev/null
+/*
+Copyright (c) 2013, IIT Madras
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+* 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.
+* 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.
+
+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.
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+*/
+// Copyright (c) 2013-2017 Bluespec, Inc. All Rights Reserved
+
+package AXI4_Fabric;
+
+// ================================================================
+// This package defines a fabric connecting CPUs, Memories and DMAs
+// and other IP blocks.
+
+// ================================================================
+// Bluespec library imports
+
+import Vector :: *;
+import FIFOF :: *;
+import ConfigReg :: *;
+
+// ----------------
+// BSV additional libs
+
+import Cur_Cycle :: *;
+
+// ================================================================
+// Project imports
+
+import Semi_FIFOF :: *;
+import AXI4_Types :: *;
+
+// ================================================================
+// The interface for the fabric module
+
+interface AXI4_Fabric_IFC #(numeric type num_masters,
+ numeric type num_slaves,
+ numeric type wd_addr,
+ numeric type wd_data,
+ numeric type wd_user);
+ method Action reset;
+ method Action set_verbosity (Bit #(4) verbosity);
+
+ // From masters
+ interface Vector #(num_masters, AXI4_Slave_IFC #(wd_addr, wd_data, wd_user)) v_from_masters;
+
+ // To slaves
+ interface Vector #(num_slaves, AXI4_Master_IFC #(wd_addr, wd_data, wd_user)) v_to_slaves;
+endinterface
+
+// ================================================================
+// The Fabric module
+// The function parameter is an address-decode function, which returns
+// returns (True, slave-port-num) if address is mapped to slave-port-num
+// (False, ?) if address is unmapped to any port
+
+module mkAXI4_Fabric #(function Tuple2 #(Bool, Bit #(TLog #(num_slaves)))
+ fn_addr_to_slave_num (Bit #(wd_addr) addr))
+ (AXI4_Fabric_IFC #(num_masters, num_slaves, wd_addr, wd_data, wd_user))
+
+ provisos (Log #(num_masters, log_nm),
+ Log #(num_slaves, log_ns),
+ Log #(TAdd #(num_masters, 1), log_nm_plus_1),
+ Log #(TAdd #(num_slaves, 1), log_ns_plus_1),
+ Add #(_dummy, TLog #(num_slaves), log_ns_plus_1));
+
+
+ // Transactors facing masters
+ Vector #(num_masters, AXI4_Slave_Xactor_IFC #(wd_addr, wd_data, wd_user))
+ xactors_from_masters <- replicateM (mkAXI4_Slave_Xactor);
+
+ // Transactors facing slaves
+ Vector #(num_slaves, AXI4_Master_Xactor_IFC #(wd_addr, wd_data, wd_user))
+ xactors_to_slaves <- replicateM (mkAXI4_Master_Xactor);
+
+ // FIFOs to keep track of which master originated a transaction, in
+ // order to route corresponding responses back to that master.
+ // Legal masters are 0..(num_masters-1)
+ // The value of 'num_masters' is used for decode errors (no such slave)
+
+ Vector #(num_masters, FIFOF #(Bit #(log_ns_plus_1))) v_f_wr_sjs <- replicateM (mkFIFOF);
+ Vector #(num_masters, FIFOF #(Bit #(wd_user))) v_f_wr_err_user <- replicateM (mkFIFOF);
+ Vector #(num_slaves, FIFOF #(Bit #(log_nm_plus_1))) v_f_wr_mis <- replicateM (mkFIFOF);
+
+ Vector #(num_masters, FIFOF #(Bit #(log_ns_plus_1))) v_f_rd_sjs <- replicateM (mkFIFOF);
+ Vector #(num_masters, FIFOF #(Bit #(wd_user))) v_f_rd_err_user <- replicateM (mkFIFOF);
+ Vector #(num_slaves, FIFOF #(Bit #(log_nm_plus_1))) v_f_rd_mis <- replicateM (mkFIFOF);
+
+ // ----------------------------------------------------------------
+ // BEHAVIOR
+
+ function Bool wr_move_from_mi_to_sj (Integer mi, Integer sj);
+ let addr = xactors_from_masters [mi].o_wr_addr.first.awaddr;
+ match { .legal, .slave_num } = fn_addr_to_slave_num (addr);
+ return (legal && (slave_num == fromInteger (sj)));
+ endfunction
+
+ function Bool wr_illegal_sj (Integer mi);
+ let addr = xactors_from_masters [mi].o_wr_addr.first.awaddr;
+ match { .legal, ._ } = fn_addr_to_slave_num (addr);
+ return (! legal);
+ endfunction
+
+ function Bool rd_move_from_mi_to_sj (Integer mi, Integer sj);
+ let addr = xactors_from_masters [mi].o_rd_addr.first.araddr;
+ match { .legal, .slave_num } = fn_addr_to_slave_num (addr);
+ return (legal && (slave_num == fromInteger (sj)));
+ endfunction
+
+ function Bool rd_illegal_sj (Integer mi);
+ let addr = xactors_from_masters [mi].o_rd_addr.first.araddr;
+ match { .legal, ._ } = fn_addr_to_slave_num (addr);
+ return (! legal);
+ endfunction
+
+ // ----------------
+ // Wr requests from masters to slaves
+
+ // Legal destination slaves
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+ for (Integer sj = 0; sj < valueOf (num_slaves); sj = sj + 1)
+
+ rule rl_wr_xaction_master_to_slave (wr_move_from_mi_to_sj (mi, sj));
+ AXI4_Wr_Addr #(wd_addr, wd_user) a <- pop_o (xactors_from_masters [mi].o_wr_addr);
+ AXI4_Wr_Data #(wd_data) d <- pop_o (xactors_from_masters [mi].o_wr_data);
+
+ xactors_to_slaves [sj].i_wr_addr.enq (a);
+ xactors_to_slaves [sj].i_wr_data.enq (d);
+
+ v_f_wr_mis [sj].enq (fromInteger (mi));
+ v_f_wr_sjs [mi].enq (fromInteger (sj));
+
+ `ifdef verbose
+ $display ($time,"\tAXI4_Fabric: wr master [%0d] -> slave [%0d]", mi, sj);
+ $display ($time,"\t ", fshow (a));
+ $display ($time,"\t ", fshow (d));
+ `endif
+ endrule
+
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+ for (Integer sj = 0; sj < valueOf (num_slaves); sj = sj + 1)
+
+ rule rl_wr_xaction_master_to_slave_data ((v_f_wr_mis [sj].first == fromInteger (mi))
+ && (v_f_wr_sjs [mi].first == fromInteger (sj)));
+ AXI4_Wr_Data #(wd_data) d <- pop_o (xactors_from_masters [mi].o_wr_data);
+ xactors_to_slaves [sj].i_wr_data.enq(d);
+ `ifdef verbose $display ($time,"\tAXI4_Fabric: Write Data -> slave[%0d] \n",sj,$time,"\t", fshow (d)); `endif
+ endrule
+
+
+ // Non-existent destination slaves
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+ rule rl_wr_xaction_no_such_slave (wr_illegal_sj (mi));
+ AXI4_Wr_Addr #(wd_addr, wd_user) a <- pop_o (xactors_from_masters [mi].o_wr_addr);
+ AXI4_Wr_Data #(wd_data) d <- pop_o (xactors_from_masters [mi].o_wr_data);
+
+ v_f_wr_sjs [mi].enq (fromInteger (valueOf (num_slaves)));
+ v_f_wr_err_user [mi].enq (a.awuser);
+ `ifdef verbose
+ $display ($time,"\tAXI4_Fabric: wr master [%0d] -> illegal addr", mi);
+ $display ($time,"\t ", fshow (a));
+ `endif
+ endrule
+
+ // ----------------
+ // Rd requests from masters to slaves
+
+ // Legal destination slaves
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+ for (Integer sj = 0; sj < valueOf (num_slaves); sj = sj + 1)
+
+ rule rl_rd_xaction_master_to_slave (rd_move_from_mi_to_sj (mi, sj));
+ AXI4_Rd_Addr #(wd_addr, wd_user) a <- pop_o (xactors_from_masters [mi].o_rd_addr);
+
+ xactors_to_slaves [sj].i_rd_addr.enq (a);
+
+ v_f_rd_mis [sj].enq (fromInteger (mi));
+ v_f_rd_sjs [mi].enq (fromInteger (sj));
+
+ `ifdef verbose
+ $display ($time,"\tAXI4_Fabric: rd master [%0d] -> slave [%0d]", mi, sj);
+ $display ($time,"\t ", fshow (a));
+ `endif
+ endrule
+
+ // Non-existent destination slaves
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+ rule rl_rd_xaction_no_such_slave (rd_illegal_sj (mi));
+ AXI4_Rd_Addr #(wd_addr, wd_user) a <- pop_o (xactors_from_masters [mi].o_rd_addr);
+
+ v_f_rd_sjs [mi].enq (fromInteger (valueOf (num_slaves)));
+ v_f_rd_err_user [mi].enq (a.aruser);
+
+ `ifdef verbose
+ $display ($time,"\tAXI4_Fabric: rd master [%0d] -> illegal addr", mi);
+ $display ($time,"\t ", fshow (a));
+ `endif
+ endrule
+
+ // ----------------
+ // Wr responses from slaves to masters
+
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+ for (Integer sj = 0; sj < valueOf (num_slaves); sj = sj + 1)
+
+ rule rl_wr_resp_slave_to_master ( (v_f_wr_mis [sj].first == fromInteger (mi))
+ && (v_f_wr_sjs [mi].first == fromInteger (sj)));
+ v_f_wr_mis [sj].deq;
+ v_f_wr_sjs [mi].deq;
+ AXI4_Wr_Resp #(wd_user) b <- pop_o (xactors_to_slaves [sj].o_wr_resp);
+
+ xactors_from_masters [mi].i_wr_resp.enq (b);
+
+ `ifdef verbose
+ $display ($time,"\tAXI4_Fabric: wr master [%0d] <- slave [%0d]", mi, sj);
+ $display ($time,"\t ", fshow (b));
+ `endif
+ endrule
+
+ // ----------------
+ // Wr error responses to masters
+ // v_f_wr_sjs [mi].first has value num_slaves (illegal value)
+ // v_f_wr_err_user [mi].first contains the request's 'user' data
+
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+
+ rule rl_wr_resp_err_to_master (v_f_wr_sjs [mi].first == fromInteger (valueOf (num_slaves)));
+ v_f_wr_sjs [mi].deq;
+ v_f_wr_err_user [mi].deq;
+
+ //let b = AXI4_Wr_Resp {bresp: AXI4_DECERR, buser: v_f_wr_err_user [mi].first};
+ let b = AXI4_Wr_Resp {bresp: AXI4_DECERR, buser: v_f_wr_err_user [mi].first, bid:fromInteger(mi)};
+
+ xactors_from_masters [mi].i_wr_resp.enq (b);
+
+ `ifdef verbose
+ $display ($time,"\tAXI4_Fabric: wr master [%0d] <- error", mi);
+ $display ($time,"\t ", fshow (b));
+ `endif
+ endrule
+
+ // ----------------
+ // Rd responses from slaves to masters
+
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+ for (Integer sj = 0; sj < valueOf (num_slaves); sj = sj + 1)
+
+ rule rl_rd_resp_slave_to_master ( (v_f_rd_mis [sj].first == fromInteger (mi))
+ && (v_f_rd_sjs [mi].first == fromInteger (sj)));
+ AXI4_Rd_Data #(wd_data, wd_user) r <- pop_o (xactors_to_slaves [sj].o_rd_data);
+
+ xactors_from_masters [mi].i_rd_data.enq (r);
+ if(r.rlast)begin
+ v_f_rd_mis [sj].deq;
+ v_f_rd_sjs [mi].deq;
+ end
+
+ `ifdef verbose
+ $display ($time,"\tAXI4_Fabric: rd master [%0d] <- slave [%0d]", mi, sj);
+ $display ($time,"\t ", fshow (r));
+ `endif
+ endrule
+
+ // ----------------
+ // Rd error responses to masters
+ // v_f_rd_sjs [mi].first has value num_slaves (illegal value)
+ // v_f_rd_err_user [mi].first contains the request's 'user' data
+
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+
+ rule rl_rd_resp_err_to_master (v_f_rd_sjs [mi].first == fromInteger (valueOf (num_slaves)));
+ v_f_rd_sjs [mi].deq;
+ v_f_rd_err_user [mi].deq;
+
+ Bit #(wd_data) data = 0;
+ let r = AXI4_Rd_Data {rresp: AXI4_DECERR, ruser: v_f_rd_err_user [mi].first, rdata: data, rlast:True,rid:fromInteger(mi)};
+
+ xactors_from_masters [mi].i_rd_data.enq (r);
+
+ `ifdef verbose
+ $display ($time,"\tAXI4_Fabric: rd master [%0d] <- error", mi);
+ $display ($time,"\t ", fshow (r));
+ `endif
+ endrule
+
+ // ----------------------------------------------------------------
+ // INTERFACE
+
+ function AXI4_Slave_IFC #(wd_addr, wd_data, wd_user) f1 (Integer j) = xactors_from_masters [j].axi_side;
+ function AXI4_Master_IFC #(wd_addr, wd_data, wd_user) f2 (Integer j) = xactors_to_slaves [j].axi_side;
+
+ method Action reset;
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1) begin
+ xactors_from_masters [mi].reset;
+
+ v_f_wr_sjs [mi].clear;
+ v_f_wr_err_user [mi].clear;
+
+ v_f_rd_sjs [mi].clear;
+ v_f_rd_err_user [mi].clear;
+ end
+
+ for (Integer sj = 0; sj < valueOf (num_slaves); sj = sj + 1) begin
+ xactors_to_slaves [sj].reset;
+ v_f_wr_mis [sj].clear;
+ v_f_rd_mis [sj].clear;
+ end
+ endmethod
+
+ interface v_from_masters = genWith (f1);
+ interface v_to_slaves = genWith (f2);
+endmodule
+
+// ================================================================
+
+endpackage: AXI4_Fabric
--- /dev/null
+/*
+Copyright (c) 2013, IIT Madras
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+* 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.
+* 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.
+
+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.
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+*/
+// Copyright (c) 2013-2017 Bluespec, Inc. All Rights Reserved
+
+package AXI4_Lite_Fabric;
+
+// ================================================================
+// This package defines a fabric connecting CPUs, Memories and DMAs
+// and other IP blocks.
+
+// ================================================================
+// Bluespec library imports
+
+import Vector :: *;
+import FIFOF :: *;
+import ConfigReg :: *;
+
+// ----------------
+// BSV additional libs
+
+import Cur_Cycle :: *;
+
+// ================================================================
+// Project imports
+
+import Semi_FIFOF :: *;
+import AXI4_Lite_Types :: *;
+
+// ================================================================
+// The interface for the fabric module
+
+interface AXI4_Lite_Fabric_IFC #(numeric type num_masters,
+ numeric type num_slaves,
+ numeric type wd_addr,
+ numeric type wd_data,
+ numeric type wd_user);
+ method Action reset;
+ method Action set_verbosity (Bit #(4) verbosity);
+
+ // From masters
+ interface Vector #(num_masters, AXI4_Lite_Slave_IFC #(wd_addr, wd_data, wd_user)) v_from_masters;
+
+ // To slaves
+ interface Vector #(num_slaves, AXI4_Lite_Master_IFC #(wd_addr, wd_data, wd_user)) v_to_slaves;
+endinterface
+
+// ================================================================
+// The Fabric module
+// The function parameter is an address-decode function, which returns
+// returns (True, slave-port-num) if address is mapped to slave-port-num
+// (False, ?) if address is unmapped to any port
+
+module mkAXI4_Lite_Fabric #(function Tuple2 #(Bool, Bit #(TLog #(num_slaves)))
+ fn_addr_to_slave_num (Bit #(wd_addr) addr))
+ (AXI4_Lite_Fabric_IFC #(num_masters, num_slaves, wd_addr, wd_data, wd_user))
+
+ provisos (Log #(num_masters, log_nm),
+ Log #(num_slaves, log_ns),
+ Log #(TAdd #(num_masters, 1), log_nm_plus_1),
+ Log #(TAdd #(num_slaves, 1), log_ns_plus_1),
+ Add #(_dummy, TLog #(num_slaves), log_ns_plus_1));
+
+ Reg #(Bit #(4)) cfg_verbosity <- mkConfigReg (0);
+
+ // Transactors facing masters
+ Vector #(num_masters, AXI4_Lite_Slave_Xactor_IFC #(wd_addr, wd_data, wd_user))
+ xactors_from_masters <- replicateM (mkAXI4_Lite_Slave_Xactor);
+
+ // Transactors facing slaves
+ Vector #(num_slaves, AXI4_Lite_Master_Xactor_IFC #(wd_addr, wd_data, wd_user))
+ xactors_to_slaves <- replicateM (mkAXI4_Lite_Master_Xactor);
+
+ // FIFOs to keep track of which master originated a transaction, in
+ // order to route corresponding responses back to that master.
+ // Legal masters are 0..(num_masters-1)
+ // The value of 'num_masters' is used for decode errors (no such slave)
+
+ Vector #(num_masters, FIFOF #(Bit #(log_ns_plus_1))) v_f_wr_sjs <- replicateM (mkFIFOF);
+ Vector #(num_masters, FIFOF #(Bit #(wd_user))) v_f_wr_err_user <- replicateM (mkFIFOF);
+ Vector #(num_slaves, FIFOF #(Bit #(log_nm_plus_1))) v_f_wr_mis <- replicateM (mkFIFOF);
+
+ Vector #(num_masters, FIFOF #(Bit #(log_ns_plus_1))) v_f_rd_sjs <- replicateM (mkFIFOF);
+ Vector #(num_masters, FIFOF #(Bit #(wd_user))) v_f_rd_err_user <- replicateM (mkFIFOF);
+ Vector #(num_slaves, FIFOF #(Bit #(log_nm_plus_1))) v_f_rd_mis <- replicateM (mkFIFOF);
+
+ // ----------------------------------------------------------------
+ // BEHAVIOR
+
+ function Bool wr_move_from_mi_to_sj (Integer mi, Integer sj);
+ let addr = xactors_from_masters [mi].o_wr_addr.first.awaddr;
+ match { .legal, .slave_num } = fn_addr_to_slave_num (addr);
+ return (legal && (slave_num == fromInteger (sj)));
+ endfunction
+
+ function Bool wr_illegal_sj (Integer mi);
+ let addr = xactors_from_masters [mi].o_wr_addr.first.awaddr;
+ match { .legal, ._ } = fn_addr_to_slave_num (addr);
+ return (! legal);
+ endfunction
+
+ function Bool rd_move_from_mi_to_sj (Integer mi, Integer sj);
+ let addr = xactors_from_masters [mi].o_rd_addr.first.araddr;
+ match { .legal, .slave_num } = fn_addr_to_slave_num (addr);
+ return (legal && (slave_num == fromInteger (sj)));
+ endfunction
+
+ function Bool rd_illegal_sj (Integer mi);
+ let addr = xactors_from_masters [mi].o_rd_addr.first.araddr;
+ match { .legal, ._ } = fn_addr_to_slave_num (addr);
+ return (! legal);
+ endfunction
+
+ // ----------------
+ // Wr requests from masters to slaves
+
+ // Legal destination slaves
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+ for (Integer sj = 0; sj < valueOf (num_slaves); sj = sj + 1)
+
+ rule rl_wr_xaction_master_to_slave (wr_move_from_mi_to_sj (mi, sj));
+ AXI4_Lite_Wr_Addr #(wd_addr, wd_user) a <- pop_o (xactors_from_masters [mi].o_wr_addr);
+ AXI4_Lite_Wr_Data #(wd_data) d <- pop_o (xactors_from_masters [mi].o_wr_data);
+
+ xactors_to_slaves [sj].i_wr_addr.enq (a);
+ xactors_to_slaves [sj].i_wr_data.enq (d);
+
+ v_f_wr_mis [sj].enq (fromInteger (mi));
+ v_f_wr_sjs [mi].enq (fromInteger (sj));
+
+ if (cfg_verbosity > 1) begin
+ $display ("%0d: AXI4_Lite_Fabric: wr master [%0d] -> slave [%0d]", cur_cycle, mi, sj);
+ $display (" ", fshow (a));
+ $display (" ", fshow (d));
+ end
+ endrule
+
+ // Non-existent destination slaves
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+ rule rl_wr_xaction_no_such_slave (wr_illegal_sj (mi));
+ AXI4_Lite_Wr_Addr #(wd_addr, wd_user) a <- pop_o (xactors_from_masters [mi].o_wr_addr);
+ AXI4_Lite_Wr_Data #(wd_data) d <- pop_o (xactors_from_masters [mi].o_wr_data);
+
+ v_f_wr_sjs [mi].enq (fromInteger (valueOf (num_slaves)));
+ v_f_wr_err_user [mi].enq (a.awuser);
+
+ if (cfg_verbosity > 1) begin
+ $display ("%0d: AXI4_Lite_Fabric: wr master [%0d] -> illegal addr", cur_cycle, mi);
+ $display (" ", fshow (a));
+ end
+ endrule
+
+ // ----------------
+ // Rd requests from masters to slaves
+
+ // Legal destination slaves
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+ for (Integer sj = 0; sj < valueOf (num_slaves); sj = sj + 1)
+
+ rule rl_rd_xaction_master_to_slave (rd_move_from_mi_to_sj (mi, sj));
+ AXI4_Lite_Rd_Addr #(wd_addr, wd_user) a <- pop_o (xactors_from_masters [mi].o_rd_addr);
+
+ xactors_to_slaves [sj].i_rd_addr.enq (a);
+
+ v_f_rd_mis [sj].enq (fromInteger (mi));
+ v_f_rd_sjs [mi].enq (fromInteger (sj));
+
+ if (cfg_verbosity > 1) begin
+ $display ("%0d: AXI4_Lite_Fabric: rd master [%0d] -> slave [%0d]", cur_cycle, mi, sj);
+ $display (" ", fshow (a));
+ end
+ endrule
+
+ // Non-existent destination slaves
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+ rule rl_rd_xaction_no_such_slave (rd_illegal_sj (mi));
+ AXI4_Lite_Rd_Addr #(wd_addr, wd_user) a <- pop_o (xactors_from_masters [mi].o_rd_addr);
+
+ v_f_rd_sjs [mi].enq (fromInteger (valueOf (num_slaves)));
+ v_f_rd_err_user [mi].enq (a.aruser);
+
+ if (cfg_verbosity > 1) begin
+ $display ("%0d: AXI4_Lite_Fabric: rd master [%0d] -> illegal addr", cur_cycle, mi);
+ $display (" ", fshow (a));
+ end
+ endrule
+
+ // ----------------
+ // Wr responses from slaves to masters
+
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+ for (Integer sj = 0; sj < valueOf (num_slaves); sj = sj + 1)
+
+ rule rl_wr_resp_slave_to_master ( (v_f_wr_mis [sj].first == fromInteger (mi))
+ && (v_f_wr_sjs [mi].first == fromInteger (sj)));
+ v_f_wr_mis [sj].deq;
+ v_f_wr_sjs [mi].deq;
+ AXI4_Lite_Wr_Resp #(wd_user) b <- pop_o (xactors_to_slaves [sj].o_wr_resp);
+
+ xactors_from_masters [mi].i_wr_resp.enq (b);
+
+ if (cfg_verbosity > 1) begin
+ $display ("%0d: AXI4_Lite_Fabric: wr master [%0d] <- slave [%0d]", cur_cycle, mi, sj);
+ $display (" ", fshow (b));
+ end
+ endrule
+
+ // ----------------
+ // Wr error responses to masters
+ // v_f_wr_sjs [mi].first has value num_slaves (illegal value)
+ // v_f_wr_err_user [mi].first contains the request's 'user' data
+
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+
+ rule rl_wr_resp_err_to_master (v_f_wr_sjs [mi].first == fromInteger (valueOf (num_slaves)));
+ v_f_wr_sjs [mi].deq;
+ v_f_wr_err_user [mi].deq;
+
+ let b = AXI4_Lite_Wr_Resp {bresp: AXI4_LITE_DECERR, buser: v_f_wr_err_user [mi].first};
+
+ xactors_from_masters [mi].i_wr_resp.enq (b);
+
+ if (cfg_verbosity > 1) begin
+ $display ("%0d: AXI4_Lite_Fabric: wr master [%0d] <- error", cur_cycle, mi);
+ $display (" ", fshow (b));
+ end
+ endrule
+
+ // ----------------
+ // Rd responses from slaves to masters
+
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+ for (Integer sj = 0; sj < valueOf (num_slaves); sj = sj + 1)
+
+ rule rl_rd_resp_slave_to_master ( (v_f_rd_mis [sj].first == fromInteger (mi))
+ && (v_f_rd_sjs [mi].first == fromInteger (sj)));
+ v_f_rd_mis [sj].deq;
+ v_f_rd_sjs [mi].deq;
+ AXI4_Lite_Rd_Data #(wd_data, wd_user) r <- pop_o (xactors_to_slaves [sj].o_rd_data);
+
+ xactors_from_masters [mi].i_rd_data.enq (r);
+
+ if (cfg_verbosity > 1) begin
+ $display ("%0d: AXI4_Lite_Fabric: rd master [%0d] <- slave [%0d]", cur_cycle, mi, sj);
+ $display (" ", fshow (r));
+ end
+ endrule
+
+ // ----------------
+ // Rd error responses to masters
+ // v_f_rd_sjs [mi].first has value num_slaves (illegal value)
+ // v_f_rd_err_user [mi].first contains the request's 'user' data
+
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1)
+
+ rule rl_rd_resp_err_to_master (v_f_rd_sjs [mi].first == fromInteger (valueOf (num_slaves)));
+ v_f_rd_sjs [mi].deq;
+ v_f_rd_err_user [mi].deq;
+
+ Bit #(wd_data) data = 0;
+ let r = AXI4_Lite_Rd_Data {rresp: AXI4_LITE_DECERR, ruser: v_f_rd_err_user [mi].first, rdata: data};
+
+ xactors_from_masters [mi].i_rd_data.enq (r);
+
+ if (cfg_verbosity > 1) begin
+ $display ("%0d: AXI4_Lite_Fabric: rd master [%0d] <- error", cur_cycle, mi);
+ $display (" ", fshow (r));
+ end
+ endrule
+
+ // ----------------------------------------------------------------
+ // INTERFACE
+
+ function AXI4_Lite_Slave_IFC #(wd_addr, wd_data, wd_user) f1 (Integer j) = xactors_from_masters [j].axi_side;
+ function AXI4_Lite_Master_IFC #(wd_addr, wd_data, wd_user) f2 (Integer j) = xactors_to_slaves [j].axi_side;
+
+ method Action reset;
+ for (Integer mi = 0; mi < valueOf (num_masters); mi = mi + 1) begin
+ xactors_from_masters [mi].reset;
+
+ v_f_wr_sjs [mi].clear;
+ v_f_wr_err_user [mi].clear;
+
+ v_f_rd_sjs [mi].clear;
+ v_f_rd_err_user [mi].clear;
+ end
+
+ for (Integer sj = 0; sj < valueOf (num_slaves); sj = sj + 1) begin
+ xactors_to_slaves [sj].reset;
+ v_f_wr_mis [sj].clear;
+ v_f_rd_mis [sj].clear;
+ end
+ endmethod
+
+ method Action set_verbosity (Bit #(4) verbosity);
+ cfg_verbosity <= verbosity;
+ endmethod
+
+ interface v_from_masters = genWith (f1);
+ interface v_to_slaves = genWith (f2);
+endmodule
+
+// ================================================================
+
+endpackage: AXI4_Lite_Fabric
Copyright (c) 2013, IIT Madras
All rights reserved.
-Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions
-are met:
-
-* Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
-* 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.
-* 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.
-
-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.
-
-------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+* 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.
+* 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.
+
+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.
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
*/
// Copyright (c) 2017 Bluespec, Inc. All Rights Reserved
package AXI4_Lite_Types;
+// ================================================================
+// Facilities for ARM AXI4-Lite, consisting of 5 independent channels:
+// Write Address, Write Data, Write Response, Read Address and Read Data
+
+// Ref: ARM document:
+// AMBA AXI and ACE Protocol Specification
+// AXI3, AXI4, and AXI4-Lite
+// ACE and ACE-Lite
+// ARM IHI 0022E (ID022613)
+// Issue E, 22 Feb 2013
+
+// See export list below
+
+// ================================================================
+// Exports
+
+export
+
+// RTL-level interfaces (signals/buses)
+AXI4_Lite_Master_IFC (..),
+AXI4_Lite_Slave_IFC (..),
+
+// Dummy slave that accepts no requests and generates no response
+// Used for tying-off unused slave interfaces on fabrics.
+dummy_AXI4_Lite_Slave_ifc,
+
+// Higher-level enums and structs for the 5 AXI4 channel payloads
+AXI4_Lite_Resp (..),
+
+AXI4_Lite_Wr_Addr (..),
+AXI4_Lite_Wr_Data (..),
+AXI4_Lite_Wr_Resp (..),
+AXI4_Lite_Rd_Addr (..),
+AXI4_Lite_Rd_Data (..),
+
+// Higher-level FIFO-like interfaces for the 5 AXI4 channels,
+AXI4_Lite_Master_Xactor_IFC (..),
+AXI4_Lite_Slave_Xactor_IFC (..),
+
+// Transactors from RTL-level interfacecs to FIFO-like interfaces.
+mkAXI4_Lite_Master_Xactor,
+mkAXI4_Lite_Slave_Xactor;
+
// ================================================================
// BSV library imports
// The (*..*) attributes ensure that when bsc compiles this to Verilog,
// we get exactly the signals specified in the ARM spec.
+interface AXI4_Lite_Master_IFC #(numeric type wd_addr,
+ numeric type wd_data,
+ numeric type wd_user);
+ // Wr Addr channel
+ (* always_ready, result="awvalid" *) method Bool m_awvalid; // out
+ (* always_ready, result="awaddr" *) method Bit #(wd_addr) m_awaddr; // out
+ (* always_ready, result="awuser" *) method Bit #(wd_user) m_awuser; // out
+ (* always_ready, result="awsize" *) method Bit #(3) m_awsize; // out
+ (* always_ready, always_enabled *) method Action m_awready ((* port="awready" *) Bool awready); // in
+
+ // Wr Data channel
+ (* always_ready, result="wvalid" *) method Bool m_wvalid; // out
+ (* always_ready, result="wdata" *) method Bit #(wd_data) m_wdata; // out
+ (* always_ready, result="wstrb" *) method Bit #(TDiv #(wd_data, 8)) m_wstrb; // out
+ (* always_ready, always_enabled *) method Action m_wready ((* port="wready" *) Bool wready); // in
+
+ // Wr Response channel
+ (* always_ready, always_enabled *)
+ method Action m_bvalid ((* port="bvalid" *) Bool bvalid, // in
+ (* port="bresp" *) Bit #(2) bresp, // in
+ (* port="buser" *) Bit #(wd_user) buser); // in
+ (* always_ready, result="bready" *)
+ method Bool m_bready; // out
+
+ // Rd Addr channel
+ (* always_ready, result="arvalid" *) method Bool m_arvalid; // out
+ (* always_ready, result="araddr" *) method Bit #(wd_addr) m_araddr; // out
+ (* always_ready, result="aruser" *) method Bit #(wd_user) m_aruser; // out
+ (* always_ready, result="arsize" *) method Bit #(3) m_arsize; // out
+ (* always_ready, always_enabled *) method Action m_arready ((* port="arready" *) Bool arready); // in
+
+ // Rd Data channel
+ (* always_ready, always_enabled *)
+ method Action m_rvalid ((* port="rvalid" *) Bool rvalid, // in
+ (* port="rresp" *) Bit #(2) rresp, // in
+ (* port="rdata" *) Bit #(wd_data) rdata, // in
+ (* port="ruser" *) Bit #(wd_user) ruser); // in
+ (* always_ready, result="rready" *)
+ method Bool m_rready; // out
+endinterface: AXI4_Lite_Master_IFC
+
+// ================================================================
+// These are the signal-level interfaces for an AXI4-Lite slave.
+// The (*..*) attributes ensure that when bsc compiles this to Verilog,
+// we get exactly the signals specified in the ARM spec.
+
interface AXI4_Lite_Slave_IFC #(numeric type wd_addr,
numeric type wd_data,
numeric type wd_user);
(* always_ready, result="ruser" *) method Bit #(wd_user) m_ruser; // out
(* always_ready, always_enabled *) method Action m_rready ((* port="rready" *) Bool rready); // in
endinterface: AXI4_Lite_Slave_IFC
+
+// ================================================================
+// Connecting signal-level interfaces
+
+instance Connectable #(AXI4_Lite_Master_IFC #(wd_addr, wd_data, wd_user),
+ AXI4_Lite_Slave_IFC #(wd_addr, wd_data, wd_user));
+
+ module mkConnection #(AXI4_Lite_Master_IFC #(wd_addr, wd_data, wd_user) axim,
+ AXI4_Lite_Slave_IFC #(wd_addr, wd_data, wd_user) axis)
+ (Empty);
+
+ (* fire_when_enabled, no_implicit_conditions *)
+ rule rl_wr_addr_channel;
+ axis.m_awvalid (axim.m_awvalid, axim.m_awaddr, axim.m_awsize, axim.m_awuser);
+ axim.m_awready (axis.m_awready);
+ endrule
+
+ (* fire_when_enabled, no_implicit_conditions *)
+ rule rl_wr_data_channel;
+ axis.m_wvalid (axim.m_wvalid, axim.m_wdata, axim.m_wstrb);
+ axim.m_wready (axis.m_wready);
+ endrule
+
+ (* fire_when_enabled, no_implicit_conditions *)
+ rule rl_wr_response_channel;
+ axim.m_bvalid (axis.m_bvalid, axis.m_bresp, axis.m_buser);
+ axis.m_bready (axim.m_bready);
+ endrule
+
+ (* fire_when_enabled, no_implicit_conditions *)
+ rule rl_rd_addr_channel;
+ axis.m_arvalid (axim.m_arvalid, axim.m_araddr, axim.m_arsize, axim.m_aruser);
+ axim.m_arready (axis.m_arready);
+ endrule
+
+ (* fire_when_enabled, no_implicit_conditions *)
+ rule rl_rd_data_channel;
+ axim.m_rvalid (axis.m_rvalid, axis.m_rresp, axis.m_rdata, axis.m_ruser);
+ axis.m_rready (axim.m_rready);
+ endrule
+ endmodule
+endinstance
+
+// ================================================================
+// AXI4-Lite dummy slave: never accepts requests, never produces responses
+
+AXI4_Lite_Slave_IFC #(wd_addr, wd_data, wd_user)
+ dummy_AXI4_Lite_Slave_ifc = interface AXI4_Lite_Slave_IFC
+ // Wr Addr channel
+ method Action m_awvalid (Bool awvalid,
+ Bit #(wd_addr) awaddr,
+ Bit #(3) awsize,
+ Bit #(wd_user) awuser);
+ noAction;
+ endmethod
+
+ method Bool m_awready;
+ return False;
+ endmethod
+
+ // Wr Data channel
+ method Action m_wvalid (Bool wvalid,
+ Bit #(wd_data) wdata,
+ Bit #(TDiv #(wd_data,8)) wstrb);
+ noAction;
+ endmethod
+
+ method Bool m_wready;
+ return False;
+ endmethod
+
+ // Wr Response channel
+ method Bool m_bvalid;
+ return False;
+ endmethod
+
+ method Bit #(2) m_bresp;
+ return 0;
+ endmethod
+
+ method Bit #(wd_user) m_buser;
+ return ?;
+ endmethod
+
+ method Action m_bready (Bool bready);
+ noAction;
+ endmethod
+
+ // Rd Addr channel
+ method Action m_arvalid (Bool arvalid,
+ Bit #(wd_addr) araddr,
+ Bit#(3) arsize,
+ Bit #(wd_user) aruser);
+ noAction;
+ endmethod
+
+ method Bool m_arready;
+ return False;
+ endmethod
+
+ // Rd Data channel
+ method Bool m_rvalid;
+ return False;
+ endmethod
+
+ method Bit #(2) m_rresp;
+ return 0;
+ endmethod
+
+ method Bit #(wd_data) m_rdata;
+ return 0;
+ endmethod
+
+ method Bit #(wd_user) m_ruser;
+ return ?;
+ endmethod
+
+ method Action m_rready (Bool rready);
+ noAction;
+ endmethod
+ endinterface;
+
+// ****************************************************************
+// ****************************************************************
+// Section: Higher-level FIFO-like interfaces and transactors
+// ****************************************************************
+// ****************************************************************
+
// ================================================================
// Higher-level types for payloads (rather than just bits)
} AXI4_Lite_Rd_Data #(numeric type wd_data, numeric type wd_user)
deriving (Bits, FShow);
+// ================================================================
+// Master transactor interface
+
+interface AXI4_Lite_Master_Xactor_IFC #(numeric type wd_addr,
+ numeric type wd_data,
+ numeric type wd_user);
+ method Action reset;
+
+ // AXI side
+ interface AXI4_Lite_Master_IFC #(wd_addr, wd_data, wd_user) axi_side;
+
+ // FIFOF side
+ interface FIFOF_I #(AXI4_Lite_Wr_Addr #(wd_addr, wd_user)) i_wr_addr;
+ interface FIFOF_I #(AXI4_Lite_Wr_Data #(wd_data)) i_wr_data;
+ interface FIFOF_O #(AXI4_Lite_Wr_Resp #(wd_user)) o_wr_resp;
+
+ interface FIFOF_I #(AXI4_Lite_Rd_Addr #(wd_addr, wd_user)) i_rd_addr;
+ interface FIFOF_O #(AXI4_Lite_Rd_Data #(wd_data, wd_user)) o_rd_data;
+endinterface: AXI4_Lite_Master_Xactor_IFC
+
+// ----------------------------------------------------------------
+// Master transactor
+
+module mkAXI4_Lite_Master_Xactor (AXI4_Lite_Master_Xactor_IFC #(wd_addr, wd_data, wd_user));
+
+ Bool unguarded = True;
+ Bool guarded = False;
+
+ // These FIFOs are guarded on BSV side, unguarded on AXI side
+ FIFOF #(AXI4_Lite_Wr_Addr #(wd_addr, wd_user)) f_wr_addr <- mkGFIFOF (guarded, unguarded);
+ FIFOF #(AXI4_Lite_Wr_Data #(wd_data)) f_wr_data <- mkGFIFOF (guarded, unguarded);
+ FIFOF #(AXI4_Lite_Wr_Resp #(wd_user)) f_wr_resp <- mkGFIFOF (unguarded, guarded);
+
+ FIFOF #(AXI4_Lite_Rd_Addr #(wd_addr, wd_user)) f_rd_addr <- mkGFIFOF (guarded, unguarded);
+ FIFOF #(AXI4_Lite_Rd_Data #(wd_data, wd_user)) f_rd_data <- mkGFIFOF (unguarded, guarded);
+
+ // ----------------------------------------------------------------
+ // INTERFACE
+
+ method Action reset;
+ f_wr_addr.clear;
+ f_wr_data.clear;
+ f_wr_resp.clear;
+ f_rd_addr.clear;
+ f_rd_data.clear;
+ endmethod
+
+ // AXI side
+ interface axi_side = interface AXI4_Lite_Master_IFC;
+ // Wr Addr channel
+ method Bool m_awvalid = f_wr_addr.notEmpty;
+ method Bit #(wd_addr) m_awaddr = f_wr_addr.first.awaddr;
+ method Bit #(wd_user) m_awuser = f_wr_addr.first.awuser;
+ method Bit #(3) m_awsize = f_wr_addr.first.awsize;
+ method Action m_awready (Bool awready);
+ if (f_wr_addr.notEmpty && awready) f_wr_addr.deq;
+ endmethod
+
+ // Wr Data channel
+ method Bool m_wvalid = f_wr_data.notEmpty;
+ method Bit #(wd_data) m_wdata = f_wr_data.first.wdata;
+ method Bit #(TDiv #(wd_data, 8)) m_wstrb = f_wr_data.first.wstrb;
+ method Action m_wready (Bool wready);
+ if (f_wr_data.notEmpty && wready) f_wr_data.deq;
+ endmethod
+
+ // Wr Response channel
+ method Action m_bvalid (Bool bvalid, Bit #(2) bresp, Bit #(wd_user) buser);
+ if (bvalid && f_wr_resp.notFull)
+ f_wr_resp.enq (AXI4_Lite_Wr_Resp {bresp: unpack (bresp), buser: buser});
+ endmethod
+
+ method Bool m_bready;
+ return f_wr_resp.notFull;
+ endmethod
+
+ // Rd Addr channel
+ method Bool m_arvalid = f_rd_addr.notEmpty;
+ method Bit #(wd_addr) m_araddr = f_rd_addr.first.araddr;
+ method Bit #(wd_user) m_aruser = f_rd_addr.first.aruser;
+ method Bit #(3) m_arsize = f_rd_addr.first.arsize;
+ method Action m_arready (Bool arready);
+ if (f_rd_addr.notEmpty && arready) f_rd_addr.deq;
+ endmethod
+
+ // Rd Data channel
+ method Action m_rvalid (Bool rvalid,
+ Bit #(2) rresp,
+ Bit #(wd_data) rdata,
+ Bit #(wd_user) ruser);
+ if (rvalid && f_rd_data.notFull)
+ f_rd_data.enq (AXI4_Lite_Rd_Data {rresp: unpack (rresp),
+ rdata: rdata,
+ ruser: ruser});
+ endmethod
+
+ method Bool m_rready;
+ return f_rd_data.notFull;
+ endmethod
+
+ endinterface;
+
+ // FIFOF side
+ interface i_wr_addr = to_FIFOF_I (f_wr_addr);
+ interface i_wr_data = to_FIFOF_I (f_wr_data);
+ interface o_wr_resp = to_FIFOF_O (f_wr_resp);
+
+ interface i_rd_addr = to_FIFOF_I (f_rd_addr);
+ interface o_rd_data = to_FIFOF_O (f_rd_data);
+endmodule: mkAXI4_Lite_Master_Xactor
+
// ================================================================
// Slave transactor interface
--- /dev/null
+/*
+Copyright (c) 2013, IIT Madras
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+* 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.
+* 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.
+
+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.
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+*/
+// Copyright (c) 2017 Bluespec, Inc. All Rights Reserved
+
+package AXI4_Types;
+
+// ================================================================
+// Facilities for ARM AXI4-Lite, consisting of 5 independent channels:
+// Write Address, Write Data, Write Response, Read Address and Read Data
+
+// Ref: ARM document:
+// AMBA AXI and ACE Protocol Specification
+// AXI3, AXI4, and AXI4-Lite
+// ACE and ACE-Lite
+// ARM IHI 0022E (ID022613)
+// Issue E, 22 Feb 2013
+
+// See export list below
+
+// ================================================================
+// Exports
+
+export
+
+// RTL-level interfaces (signals/buses)
+AXI4_Master_IFC (..),
+AXI4_Slave_IFC (..),
+
+// Dummy slave that accepts no requests and generates no response
+// Used for tying-off unused slave interfaces on fabrics.
+dummy_AXI4_Slave_ifc,
+
+// Higher-level enums and structs for the 5 AXI4 channel payloads
+AXI4_Resp (..),
+
+AXI4_Wr_Addr (..),
+AXI4_Wr_Data (..),
+AXI4_Wr_Resp (..),
+AXI4_Rd_Addr (..),
+AXI4_Rd_Data (..),
+
+// Higher-level FIFO-like interfaces for the 5 AXI4 channels,
+AXI4_Master_Xactor_IFC (..),
+AXI4_Slave_Xactor_IFC (..),
+
+// Transactors from RTL-level interfacecs to FIFO-like interfaces.
+mkAXI4_Master_Xactor,
+mkAXI4_Slave_Xactor;
+
+// ================================================================
+// BSV library imports
+
+import FIFOF :: *;
+import Connectable :: *;
+
+// ----------------
+// BSV additional libs
+
+import Semi_FIFOF :: *;
+
+// ****************************************************************
+// ****************************************************************
+// Section: RTL-level interfaces
+// ****************************************************************
+// ****************************************************************
+
+// ================================================================
+// These are the signal-level interfaces for an AXI4-Lite master.
+// The (*..*) attributes ensure that when bsc compiles this to Verilog,
+// we get exactly the signals specified in the ARM spec.
+
+interface AXI4_Master_IFC #(numeric type wd_addr,
+ numeric type wd_data,
+ numeric type wd_user);
+ // Wr Addr channel
+ (* always_ready, result="awvalid" *) method Bool m_awvalid; // out
+ (* always_ready, result="awaddr" *) method Bit #(wd_addr) m_awaddr; // out
+ (* always_ready, result="awuser" *) method Bit #(wd_user) m_awuser; // out
+ (* always_ready, result="awlen" *) method Bit #(8) m_awlen; // out
+ (* always_ready, result="awsize" *) method Bit #(3) m_awsize; // out
+ (* always_ready, result="awburst" *) method Bit #(2) m_awburst; // out
+ (* always_ready, result="awid" *) method Bit #(4) m_awid; // out
+ (* always_ready, always_enabled *) method Action m_awready ((* port="awready" *) Bool awready); // in
+
+ // Wr Data channel
+ (* always_ready, result="wvalid" *) method Bool m_wvalid; // out
+ (* always_ready, result="wdata" *) method Bit #(wd_data) m_wdata; // out
+ (* always_ready, result="wstrb" *) method Bit #(TDiv #(wd_data, 8)) m_wstrb; // out
+ (* always_ready, result="wlast" *) method Bool m_wlast; // out
+ (* always_ready, result="wid" *) method Bit #(4) m_wid; // out
+ (* always_ready, always_enabled *) method Action m_wready ((* port="wready" *) Bool wready); // in
+
+ // Wr Response channel
+ (* always_ready, always_enabled *)
+ method Action m_bvalid ((* port="bvalid" *) Bool bvalid, // in
+ (* port="bresp" *) Bit #(2) bresp, // in
+ (* port="buser" *) Bit #(wd_user) buser, // in
+ (* port="bid"*) Bit#(4) bid); // in
+ (* always_ready, result="bready" *)
+ method Bool m_bready; // out
+
+ // Rd Addr channel
+ (* always_ready, result="arvalid" *) method Bool m_arvalid; // out
+ (* always_ready, result="araddr" *) method Bit #(wd_addr) m_araddr; // out
+ (* always_ready, result="aruser" *) method Bit #(wd_user) m_aruser; // out
+ (* always_ready, result="arlen" *) method Bit #(8) m_arlen; // out
+ (* always_ready, result="arsize" *) method Bit #(3) m_arsize; // out
+ (* always_ready, result="arburst" *) method Bit #(2) m_arburst; // out
+ (* always_ready, result="arid" *) method Bit #(4) m_arid; // out
+ (* always_ready, always_enabled *) method Action m_arready ((* port="arready" *) Bool arready); // in
+
+ // Rd Data channel
+ (* always_ready, always_enabled *)
+ method Action m_rvalid ((* port="rvalid" *) Bool rvalid, // in
+ (* port="rresp" *) Bit #(2) rresp, // in
+ (* port="rdata" *) Bit #(wd_data) rdata, // in
+ (* port="rlast" *) Bool rlast, // in
+ (* port="ruser" *) Bit #(wd_user) ruser, // in
+ (* port="rid" *) Bit #(4) rid); // in
+ (* always_ready, result="rready" *)
+ method Bool m_rready; // out
+endinterface: AXI4_Master_IFC
+
+// ================================================================
+// These are the signal-level interfaces for an AXI4-Lite slave.
+// The (*..*) attributes ensure that when bsc compiles this to Verilog,
+// we get exactly the signals specified in the ARM spec.
+
+interface AXI4_Slave_IFC #(numeric type wd_addr,
+ numeric type wd_data,
+ numeric type wd_user);
+ // Wr Addr channel
+ (* always_ready, always_enabled *)
+ method Action m_awvalid ((* port="awvalid" *) Bool awvalid, // in
+ (* port="awaddr" *) Bit #(wd_addr) awaddr, // in
+ (* port="awsize" *) Bit #(3) awsize, // in
+ (* port="awuser" *) Bit #(wd_user) awuser, // in
+ (* port="awlen" *) Bit #(8) awlen, // in
+ (* port="awburst" *) Bit #(2) awburst, // in
+ (* port="awid" *) Bit#(4) awid);
+ (* always_ready, result="awready" *)
+ method Bool m_awready; // out
+
+ // Wr Data channel
+ (* always_ready, always_enabled *)
+ method Action m_wvalid ((* port="wvalid" *) Bool wvalid, // in
+ (* port="wdata" *) Bit #(wd_data) wdata, // in
+ (* port="wstrb" *) Bit #(TDiv #(wd_data,8)) wstrb, // in
+ (* port="wlast" *) Bool wlast,
+ (* port="wid" *) Bit#(4) wid);
+ (* always_ready, result="wready" *)
+ method Bool m_wready; // out
+
+ // Wr Response channel
+ (* always_ready, result="bvalid" *) method Bool m_bvalid; // out
+ (* always_ready, result="bresp" *) method Bit #(2) m_bresp; // out
+ (* always_ready, result="buser" *) method Bit #(wd_user) m_buser; // out
+ (* always_ready, result="bid" *) method Bit #(4) m_bid; // out
+ (* always_ready, always_enabled *) method Action m_bready ((* port="bready" *) Bool bready); // in
+
+ // Rd Addr channel
+ (* always_ready, always_enabled *)
+ method Action m_arvalid ((* port="arvalid" *) Bool arvalid, // in
+ (* port="araddr" *) Bit #(wd_addr) araddr, // in
+ (* port="arsize" *) Bit #(3) arsize, // in
+ (* port="aruser" *) Bit #(wd_user) aruser, // in
+ (* port="arlen" *) Bit #(8) arlen, // in
+ (* port="arburst" *) Bit #(2) arburst, // in
+ (* port="arid" *) Bit#(4) arid
+ );
+ (* always_ready, result="arready" *)
+ method Bool m_arready; // out
+
+ // Rd Data channel
+ (* always_ready, result="rvalid" *) method Bool m_rvalid; // out
+ (* always_ready, result="rresp" *) method Bit #(2) m_rresp; // out
+ (* always_ready, result="rdata" *) method Bit #(wd_data) m_rdata; // out
+ (* always_ready, result="rlast" *) method Bool m_rlast; // out
+ (* always_ready, result="ruser" *) method Bit #(wd_user) m_ruser; // out
+ (* always_ready, result="rid" *) method Bit #(4) m_rid; // out
+ (* always_ready, always_enabled *) method Action m_rready ((* port="rready" *) Bool rready); // in
+endinterface: AXI4_Slave_IFC
+
+// ================================================================
+// Connecting signal-level interfaces
+
+instance Connectable #(AXI4_Master_IFC #(wd_addr, wd_data, wd_user),
+ AXI4_Slave_IFC #(wd_addr, wd_data, wd_user));
+
+ module mkConnection #(AXI4_Master_IFC #(wd_addr, wd_data, wd_user) axim,
+ AXI4_Slave_IFC #(wd_addr, wd_data, wd_user) axis)
+ (Empty);
+
+ (* fire_when_enabled, no_implicit_conditions *)
+ rule rl_wr_addr_channel;
+ axis.m_awvalid (axim.m_awvalid, axim.m_awaddr, axim.m_awsize, axim.m_awuser, axim.m_awlen, axim.m_awburst, axim.m_awid);
+ axim.m_awready (axis.m_awready);
+ endrule
+
+ (* fire_when_enabled, no_implicit_conditions *)
+ rule rl_wr_data_channel;
+ axis.m_wvalid (axim.m_wvalid, axim.m_wdata, axim.m_wstrb, axim.m_wlast, axim.m_wid);
+ axim.m_wready (axis.m_wready);
+ endrule
+
+ (* fire_when_enabled, no_implicit_conditions *)
+ rule rl_wr_response_channel;
+ axim.m_bvalid (axis.m_bvalid, axis.m_bresp, axis.m_buser, axis.m_bid);
+ axis.m_bready (axim.m_bready);
+ endrule
+
+ (* fire_when_enabled, no_implicit_conditions *)
+ rule rl_rd_addr_channel;
+ axis.m_arvalid (axim.m_arvalid, axim.m_araddr, axim.m_arsize, axim.m_aruser, axim.m_arlen, axim.m_arburst, axim.m_arid);
+ axim.m_arready (axis.m_arready);
+ endrule
+
+ (* fire_when_enabled, no_implicit_conditions *)
+ rule rl_rd_data_channel;
+ axim.m_rvalid (axis.m_rvalid, axis.m_rresp, axis.m_rdata, axis.m_rlast, axis.m_ruser, axis.m_rid);
+ axis.m_rready (axim.m_rready);
+ endrule
+ endmodule
+endinstance
+
+// ================================================================
+// AXI4-Lite dummy slave: never accepts requests, never produces responses
+
+AXI4_Slave_IFC #(wd_addr, wd_data, wd_user)
+ dummy_AXI4_Slave_ifc = interface AXI4_Slave_IFC
+ // Wr Addr channel
+ method Action m_awvalid (Bool awvalid,
+ Bit #(wd_addr) awaddr,
+ Bit #(3) awsize,
+ Bit #(wd_user) awuser,
+ Bit #(8) awlen,
+ Bit #(2) awburst,
+ Bit #(4) awid);
+ noAction;
+ endmethod
+
+ method Bool m_awready;
+ return False;
+ endmethod
+
+ // Wr Data channel
+ method Action m_wvalid (Bool wvalid,
+ Bit #(wd_data) wdata,
+ Bit #(TDiv #(wd_data,8)) wstrb,
+ Bool wlast,
+ Bit#(4) wid);
+ noAction;
+ endmethod
+
+ method Bool m_wready;
+ return False;
+ endmethod
+
+ // Wr Response channel
+ method Bool m_bvalid;
+ return False;
+ endmethod
+
+ method Bit #(2) m_bresp;
+ return 0;
+ endmethod
+
+ method Bit #(wd_user) m_buser;
+ return ?;
+ endmethod
+ method Bit #(4) m_bid;
+ return ?;
+ endmethod
+
+ method Action m_bready (Bool bready);
+ noAction;
+ endmethod
+
+ // Rd Addr channel
+ method Action m_arvalid (Bool arvalid,
+ Bit #(wd_addr) araddr,
+ Bit#(3) arsize,
+ Bit #(wd_user) aruser,
+ Bit#(8) arlen,
+ Bit#(2) arburst,
+ Bit#(4) arid);
+ noAction;
+ endmethod
+
+ method Bool m_arready;
+ return False;
+ endmethod
+
+ // Rd Data channel
+ method Bool m_rvalid;
+ return False;
+ endmethod
+
+ method Bit #(2) m_rresp;
+ return 0;
+ endmethod
+
+ method Bit #(wd_data) m_rdata;
+ return 0;
+ endmethod
+ method Bool m_rlast;
+ return ?;
+ endmethod
+
+ method Bit #(wd_user) m_ruser;
+ return ?;
+ endmethod
+
+ method Action m_rready (Bool rready);
+ noAction;
+ endmethod
+ endinterface;
+
+// ****************************************************************
+// ****************************************************************
+// Section: Higher-level FIFO-like interfaces and transactors
+// ****************************************************************
+// ****************************************************************
+
+// ================================================================
+// Higher-level types for payloads (rather than just bits)
+
+typedef enum { AXI4_OKAY, AXI4_EXOKAY, AXI4_SLVERR, AXI4_DECERR } AXI4_Resp
+deriving (Bits, Eq, FShow);
+
+// Write Address channel
+
+typedef struct {
+ Bit #(wd_addr) awaddr;
+ Bit #(wd_user) awuser;
+ Bit#(8) awlen;
+ Bit#(3) awsize;
+ Bit#(2) awburst;
+ Bit#(4) awid;
+ } AXI4_Wr_Addr #(numeric type wd_addr, numeric type wd_user)
+deriving (Bits, FShow);
+
+// Write Data channel
+
+typedef struct {
+ Bit #(wd_data) wdata;
+ Bit #(TDiv #(wd_data, 8)) wstrb;
+ Bit#(4) wid;
+ Bool wlast;
+ } AXI4_Wr_Data #(numeric type wd_data)
+deriving (Bits, FShow);
+
+// Write Response channel
+
+typedef struct {
+ AXI4_Resp bresp;
+ Bit #(wd_user) buser;
+ Bit#(4) bid;
+ } AXI4_Wr_Resp #(numeric type wd_user)
+deriving (Bits, FShow);
+
+// Read Address channel
+
+typedef struct {
+ Bit #(wd_addr) araddr;
+ Bit #(wd_user) aruser;
+ Bit#(3) arsize;
+ Bit#(8) arlen;
+ Bit#(2) arburst;
+ Bit#(4) arid;
+ } AXI4_Rd_Addr #(numeric type wd_addr, numeric type wd_user)
+deriving (Bits, FShow);
+
+// Read Data channel
+
+typedef struct {
+ AXI4_Resp rresp;
+ Bit #(wd_data) rdata;
+ Bool rlast;
+ Bit #(wd_user) ruser;
+ Bit#(4) rid;
+ } AXI4_Rd_Data #(numeric type wd_data, numeric type wd_user)
+deriving (Bits, FShow);
+
+// ================================================================
+// Master transactor interface
+
+interface AXI4_Master_Xactor_IFC #(numeric type wd_addr,
+ numeric type wd_data,
+ numeric type wd_user);
+ method Action reset;
+
+ // AXI side
+ interface AXI4_Master_IFC #(wd_addr, wd_data, wd_user) axi_side;
+
+ // FIFOF side
+ interface FIFOF_I #(AXI4_Wr_Addr #(wd_addr, wd_user)) i_wr_addr;
+ interface FIFOF_I #(AXI4_Wr_Data #(wd_data)) i_wr_data;
+ interface FIFOF_O #(AXI4_Wr_Resp #(wd_user)) o_wr_resp;
+
+ interface FIFOF_I #(AXI4_Rd_Addr #(wd_addr, wd_user)) i_rd_addr;
+ interface FIFOF_O #(AXI4_Rd_Data #(wd_data, wd_user)) o_rd_data;
+endinterface: AXI4_Master_Xactor_IFC
+
+// ----------------------------------------------------------------
+// Master transactor
+
+module mkAXI4_Master_Xactor (AXI4_Master_Xactor_IFC #(wd_addr, wd_data, wd_user));
+
+ Bool unguarded = True;
+ Bool guarded = False;
+
+ // These FIFOs are guarded on BSV side, unguarded on AXI side
+ FIFOF #(AXI4_Wr_Addr #(wd_addr, wd_user)) f_wr_addr <- mkGFIFOF (guarded, unguarded);
+ FIFOF #(AXI4_Wr_Data #(wd_data)) f_wr_data <- mkGFIFOF (guarded, unguarded);
+ FIFOF #(AXI4_Wr_Resp #(wd_user)) f_wr_resp <- mkGFIFOF (unguarded, guarded);
+
+ FIFOF #(AXI4_Rd_Addr #(wd_addr, wd_user)) f_rd_addr <- mkGFIFOF (guarded, unguarded);
+ FIFOF #(AXI4_Rd_Data #(wd_data, wd_user)) f_rd_data <- mkGFIFOF (unguarded, guarded);
+
+ // ----------------------------------------------------------------
+ // INTERFACE
+
+ method Action reset;
+ f_wr_addr.clear;
+ f_wr_data.clear;
+ f_wr_resp.clear;
+ f_rd_addr.clear;
+ f_rd_data.clear;
+ endmethod
+
+ // AXI side
+ interface axi_side = interface AXI4_Master_IFC;
+ // Wr Addr channel
+ method Bool m_awvalid = f_wr_addr.notEmpty;
+ method Bit #(wd_addr) m_awaddr = f_wr_addr.first.awaddr;
+ method Bit #(wd_user) m_awuser = f_wr_addr.first.awuser;
+ method Bit #(8) m_awlen = f_wr_addr.first.awlen;
+ method Bit #(3) m_awsize = f_wr_addr.first.awsize;
+ method Bit #(2) m_awburst = f_wr_addr.first.awburst;
+ method Bit #(4) m_awid = f_wr_addr.first.awid;
+ method Action m_awready (Bool awready);
+ if (f_wr_addr.notEmpty && awready) f_wr_addr.deq;
+ endmethod
+
+ // Wr Data channel
+ method Bool m_wvalid = f_wr_data.notEmpty;
+ method Bit #(wd_data) m_wdata = f_wr_data.first.wdata;
+ method Bit #(TDiv #(wd_data, 8)) m_wstrb = f_wr_data.first.wstrb;
+ method Bool m_wlast = f_wr_data.first.wlast;
+ method Bit#(4) m_wid = f_wr_data.first.wid;
+ method Action m_wready (Bool wready);
+ if (f_wr_data.notEmpty && wready) f_wr_data.deq;
+ endmethod
+
+ // Wr Response channel
+ method Action m_bvalid (Bool bvalid, Bit #(2) bresp, Bit #(wd_user) buser, Bit#(4) bid);
+ if (bvalid && f_wr_resp.notFull)
+ f_wr_resp.enq (AXI4_Wr_Resp {bresp: unpack (bresp), buser: buser, bid:bid});
+ endmethod
+
+ method Bool m_bready;
+ return f_wr_resp.notFull;
+ endmethod
+
+ // Rd Addr channel
+ method Bool m_arvalid = f_rd_addr.notEmpty;
+ method Bit #(wd_addr) m_araddr = f_rd_addr.first.araddr;
+ method Bit #(wd_user) m_aruser = f_rd_addr.first.aruser;
+ method Bit #(3) m_arsize = f_rd_addr.first.arsize;
+ method Bit #(8) m_arlen = f_rd_addr.first.arlen;
+ method Bit #(2) m_arburst = f_rd_addr.first.arburst;
+ method Bit #(4) m_arid = f_rd_addr.first.arid;
+ method Action m_arready (Bool arready);
+ if (f_rd_addr.notEmpty && arready) f_rd_addr.deq;
+ endmethod
+
+ // Rd Data channel
+ method Action m_rvalid (Bool rvalid,
+ Bit #(2) rresp,
+ Bit #(wd_data) rdata,
+ Bool rlast,
+ Bit #(wd_user) ruser,
+ Bit#(4) rid);
+ if (rvalid && f_rd_data.notFull)
+ f_rd_data.enq (AXI4_Rd_Data {rresp: unpack (rresp),
+ rdata: rdata,
+ rlast: rlast,
+ ruser: ruser,
+ rid: rid});
+ endmethod
+
+ method Bool m_rready;
+ return f_rd_data.notFull;
+ endmethod
+
+ endinterface;
+
+ // FIFOF side
+ interface i_wr_addr = to_FIFOF_I (f_wr_addr);
+ interface i_wr_data = to_FIFOF_I (f_wr_data);
+ interface o_wr_resp = to_FIFOF_O (f_wr_resp);
+
+ interface i_rd_addr = to_FIFOF_I (f_rd_addr);
+ interface o_rd_data = to_FIFOF_O (f_rd_data);
+endmodule: mkAXI4_Master_Xactor
+
+// ================================================================
+// Slave transactor interface
+
+interface AXI4_Slave_Xactor_IFC #(numeric type wd_addr,
+ numeric type wd_data,
+ numeric type wd_user);
+ method Action reset;
+
+ // AXI side
+ interface AXI4_Slave_IFC #(wd_addr, wd_data, wd_user) axi_side;
+
+ // FIFOF side
+ interface FIFOF_O #(AXI4_Wr_Addr #(wd_addr, wd_user)) o_wr_addr;
+ interface FIFOF_O #(AXI4_Wr_Data #(wd_data)) o_wr_data;
+ interface FIFOF_I #(AXI4_Wr_Resp #(wd_user)) i_wr_resp;
+
+ interface FIFOF_O #(AXI4_Rd_Addr #(wd_addr, wd_user)) o_rd_addr;
+ interface FIFOF_I #(AXI4_Rd_Data #(wd_data, wd_user)) i_rd_data;
+endinterface: AXI4_Slave_Xactor_IFC
+
+// ----------------------------------------------------------------
+// Slave transactor
+
+module mkAXI4_Slave_Xactor (AXI4_Slave_Xactor_IFC #(wd_addr, wd_data, wd_user));
+
+ Bool unguarded = True;
+ Bool guarded = False;
+
+ // These FIFOs are guarded on BSV side, unguarded on AXI side
+ FIFOF #(AXI4_Wr_Addr #(wd_addr, wd_user)) f_wr_addr <- mkGFIFOF (unguarded, guarded);
+ FIFOF #(AXI4_Wr_Data #(wd_data)) f_wr_data <- mkGFIFOF (unguarded, guarded);
+ FIFOF #(AXI4_Wr_Resp #(wd_user)) f_wr_resp <- mkGFIFOF (guarded, unguarded);
+
+ FIFOF #(AXI4_Rd_Addr #(wd_addr, wd_user)) f_rd_addr <- mkGFIFOF (unguarded, guarded);
+ FIFOF #(AXI4_Rd_Data #(wd_data, wd_user)) f_rd_data <- mkGFIFOF (guarded, unguarded);
+
+ // ----------------------------------------------------------------
+ // INTERFACE
+
+ method Action reset;
+ f_wr_addr.clear;
+ f_wr_data.clear;
+ f_wr_resp.clear;
+ f_rd_addr.clear;
+ f_rd_data.clear;
+ endmethod
+
+ // AXI side
+ interface axi_side = interface AXI4_Slave_IFC;
+ // Wr Addr channel
+ method Action m_awvalid (Bool awvalid,
+ Bit #(wd_addr) awaddr,
+ Bit#(3) awsize,
+ Bit #(wd_user) awuser,
+ Bit#(8) awlen,
+ Bit#(2) awburst,
+ Bit#(4) awid);
+ if (awvalid && f_wr_addr.notFull)
+ f_wr_addr.enq (AXI4_Wr_Addr {awaddr: awaddr,
+ awsize:awsize,
+ awuser: awuser,
+ awlen:awlen,
+ awburst:awburst,
+ awid:awid});
+ endmethod
+
+ method Bool m_awready;
+ return f_wr_addr.notFull;
+ endmethod
+
+ // Wr Data channel
+ method Action m_wvalid (Bool wvalid,
+ Bit #(wd_data) wdata,
+ Bit #(TDiv #(wd_data, 8)) wstrb,
+ Bool wlast,
+ Bit#(4) wid);
+ if (wvalid && f_wr_data.notFull)
+ f_wr_data.enq (AXI4_Wr_Data {wdata: wdata, wstrb: wstrb, wlast:wlast, wid:wid});
+ endmethod
+
+ method Bool m_wready;
+ return f_wr_data.notFull;
+ endmethod
+
+ // Wr Response channel
+ method Bool m_bvalid = f_wr_resp.notEmpty;
+ method Bit #(2) m_bresp = pack (f_wr_resp.first.bresp);
+ method Bit #(wd_user) m_buser = f_wr_resp.first.buser;
+ method Bit #(4) m_bid = f_wr_resp.first.bid;
+ method Action m_bready (Bool bready);
+ if (bready && f_wr_resp.notEmpty)
+ f_wr_resp.deq;
+ endmethod
+
+ // Rd Addr channel
+ method Action m_arvalid (Bool arvalid,
+ Bit #(wd_addr) araddr,
+ Bit#(3) arsize,
+ Bit #(wd_user) aruser,
+ Bit#(8) arlen,
+ Bit#(2) arburst,
+ Bit#(4) arid);
+ if (arvalid && f_rd_addr.notFull)
+ f_rd_addr.enq (AXI4_Rd_Addr {araddr: araddr,
+ arsize: arsize,
+ aruser: aruser,
+ arlen : arlen,
+ arburst:arburst,
+ arid:arid});
+ endmethod
+
+ method Bool m_arready;
+ return f_rd_addr.notFull;
+ endmethod
+
+ // Rd Data channel
+ method Bool m_rvalid = f_rd_data.notEmpty;
+ method Bit #(2) m_rresp = pack (f_rd_data.first.rresp);
+ method Bit #(wd_data) m_rdata = f_rd_data.first.rdata;
+ method Bool m_rlast = f_rd_data.first.rlast;
+ method Bit #(wd_user) m_ruser = f_rd_data.first.ruser;
+ method Bit#(4) m_rid=f_rd_data.first.rid;
+ method Action m_rready (Bool rready);
+ if (rready && f_rd_data.notEmpty)
+ f_rd_data.deq;
+ endmethod
+ endinterface;
+
+ // FIFOF side
+ interface o_wr_addr = to_FIFOF_O (f_wr_addr);
+ interface o_wr_data = to_FIFOF_O (f_wr_data);
+ interface i_wr_resp = to_FIFOF_I (f_wr_resp);
+
+ interface o_rd_addr = to_FIFOF_O (f_rd_addr);
+ interface i_rd_data = to_FIFOF_I (f_rd_data);
+endmodule: mkAXI4_Slave_Xactor
+
+// ================================================================
+
+endpackage
--- /dev/null
+/*
+Copyright (c) 2013, IIT Madras
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+* 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.
+* 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.
+
+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.
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+*/
+// Copyright (c) 2013-2017 Bluespec, Inc. All Rights Reserved.
+
+package Cur_Cycle;
+
+// ================================================================
+// A convenience function to return the current cycle number during BSV simulations
+
+ActionValue #(Bit #(32)) cur_cycle = actionvalue
+ Bit #(32) t <- $stime;
+ return t / 10;
+ endactionvalue;
+
+// ================================================================
+
+endpackage
--- /dev/null
+### Makefile for the srio
+
+TOP_MODULE:=mkslow_peripherals
+TOP_FILE:=slow_peripherals.bsv
+HOMEDIR:=./
+TOP_DIR:=./
+BSVBUILDDIR:=./build/
+VERILOGDIR:=./verilog/
+BSVINCDIR:= .:%/Prelude:%/Libraries:%/Libraries/BlueNoC
+FPGA=xc7a100tcsg324-1
+export HOMEDIR=./
+export TOP=$(TOP_MODULE)
+
+default: full_clean compile link simulate
+
+timing_area: full_clean generate_verilog vivado_build
+
+.PHONY: compile
+compile:
+ @echo Compiling $(TOP_MODULE)....
+ @mkdir -p $(BSVBUILDDIR)
+ @bsc -u -sim -simdir $(BSVBUILDDIR) -bdir $(BSVBUILDDIR) -info-dir $(BSVBUILDDIR) -keep-fires -p $(BSVINCDIR) -D NAME=neel -g $(TOP_MODULE) $(TOP_DIR)/$(TOP_FILE)
+ @echo Compilation finished
+
+.PHONY: link
+link:
+ @echo Linking $(TOP_MODULE)...
+ @mkdir -p bin
+ @bsc -e $(TOP_MODULE) -sim -o ./bin/out -simdir $(BSVBUILDDIR) -p .:%/Prelude:%/Libraries:%/Libraries/BlueNoC:./c_files -keep-fires -bdir $(BSVBUILDDIR) -keep-fires ./c_files/checker.c
+ @echo Linking finished
+
+.PHONY: generate_verilog
+generate_verilog:
+ @echo Compiling $(TOP_MODULE) in verilog ...
+ @mkdir -p $(BSVBUILDDIR);
+ @mkdir -p $(VERILOGDIR);
+ @bsc -u -verilog -elab -vdir $(VERILOGDIR) -bdir $(BSVBUILDDIR) -info-dir $(BSVBUILDDIR)\
+ $(define_macros) -D verilog=True $(BSVCOMPILEOPTS) -verilog-filter ${BLUESPECDIR}/bin/basicinout\
+ -p $(BSVINCDIR) -g $(TOP_MODULE) $(TOP_DIR)/$(TOP_FILE) || (echo "BSC COMPILE ERROR"; exit 1)
+
+.PHONY: simulate
+simulate:
+ @echo Simulation...
+ ./bin/out
+ @echo Simulation finished.
+
+.PHONY: clean
+clean:
+ rm -rf build bin *.jou *.log
+
+.PHONY: full_clean
+full_clean: clean
+ rm -rf verilog fpga
--- /dev/null
+package axi_addr_generator;
+ /*=== Project imports ===*/
+ import defined_types::*;
+ `include "instance_defines.bsv"
+ /*=======================*/
+
+ // This function is used by the slaves on the AXI4 bus to generate the sequential addresses in burst mode.
+ // the different modes supported are :
+ // FIXED: the same address is sent in all transactions. Typically used in polling modes.
+ // INCR: The address is simply incremented arlen number of times from the starting address.
+ // WRAP: This mode supports only 4 valid lengths: 2, 4 8 and 16 bursts. the increments happen in a wrap arouind fashion.
+ function Bit#(`PADDR) burst_address_generator(Bit#(8) arlen, Bit#(3) arsize, Bit#(2) arburst, Bit#(`PADDR) address);
+
+ // this variable will decide the index above which part of the address should
+ // not change in WRAP mode. Bits below this index value be incremented according
+ // to the value of arlen and arsize;
+ Bit#(3) wrap_size;
+ case(arlen)
+ 3: wrap_size= 2;
+ 7: wrap_size= 3;
+ 15: wrap_size=4;
+ default:wrap_size=1;
+ endcase
+
+ Bit#(`PADDR) new_address=address+(('b1)<<arsize); // this is address will directly be used for INCR mode.
+ Bit#(`PADDR) mask;
+ mask=('1)<<(arsize+wrap_size); // create a mask for bits which will remain constant in wrap mode.
+ Bit#(`PADDR) temp1=address& mask; // capture the constant part of the address in WRAP mode.
+ Bit#(`PADDR) temp2=new_address& (~mask); // capture the incremental part of the address in WRAP mode.
+
+ if(arburst==0) // FIXED
+ return address;
+ else if(arburst==1)begin // INCR
+ return new_address;
+ end
+ else begin // WRAP
+ return temp1|temp2; // create the new address in the wrap mode by ORing the masked values.
+ end
+ endfunction
+endpackage
--- /dev/null
+/*
+Copyright (c) 2013, IIT Madras
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+* 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.
+* 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.
+
+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.
+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
+
+Author Names : Neel Gala, Arjun Menon
+Email ID : neelgala@gmail.com
+
+Description :
+
+This files contains all the types and structures that are used in any of the modules.
+*/
+package defined_types;
+
+`include "instance_defines.bsv"
+
+ typedef enum {Load, Store, Atomic, Fence} Access_type deriving (Bits,Eq,FShow);
+ typedef enum {User=2'd0,Supervisor=2'd1,Machine=2'd3} Privilege_mode deriving (Bits,Eq,FShow);
+ typedef enum {Idle,Stall,Handling_Request,Handling_Memory_Read, Handling_Memory_Write, Handle_Fence} Cache_State deriving (Bits,Eq,FShow);
+ typedef enum {Check_vd,Update_vd} Fence_state deriving (Bits,Eq);
+ typedef enum {AccessFlush,Fence,None} Flush_type deriving (Bits,Eq,FShow);
+
+ typedef union tagged{
+ Bit#(width) Present;
+ Bit#(4) Absent;
+ } RFType#(numeric type width) deriving(Bits,Eq,FShow);
+
+ typedef union tagged{
+ void All;
+ void None;
+ Bit#(TLog#(`PRFDEPTH)) Specific;
+ }PRFFlush deriving(Bits, Eq, FShow);
+
+ typedef union tagged{
+ void All;
+ void None;
+ Tuple2#(Register_type, Bit#(5)) Specific;
+ }RFFlush deriving(Bits, Eq, FShow);
+
+
+ typedef struct{
+ Bit#(addr_width) address;
+ }From_Cpu#(numeric type addr_width) deriving(Bits,Eq);
+
+ typedef struct{
+ Bit#(TMul#(word_size,8)) data_word;
+ Bit#(1) bus_error;
+ Bit#(1) misaligned_error;
+ Bit#(addr_width) address;
+ }To_Cpu#(numeric type addr_width,numeric type word_size) deriving(Bits,Eq);
+
+ typedef struct{
+ Bit#(addr_width) address;
+ Bit#(8) burst_length;
+ Access_type ld_st;
+ Bit#(3) transfer_size;
+ }To_Memory#(numeric type addr_width) deriving(Bits,Eq);
+
+ typedef struct{
+ Bit#(TMul#(word_size,8)) data_line;
+ Bit#(1) bus_error;
+ Bool last_word;
+ }From_Memory#(numeric type word_size) deriving(Bits,Eq);
+
+ typedef struct{
+ //Bit#(addr_width) address;
+ Access_type load_store;
+ Bit#(TMul#(word_size,8)) data;
+ Bit#(TLog#(TDiv#(addr_width, 8))) transfer_size; // 0 -8 bits, 1- 16 bits, 2 -32 bits 3 - 64-bits;
+ `ifdef atomic Bit#(5) atomic_op;`endif
+ Bool signextend;
+ }From_Cpu_D#(numeric type addr_width, numeric type word_size) deriving(Bits,Eq,FShow);
+
+
+ typedef struct{
+ Bit#(TMul#(8,TMul#(word_size,block_size))) line;
+ Bit#(addr_width) address;
+ Bit#(TLog#(ways)) replace_block;
+ } Current_Store#(numeric type ways, numeric type addr_width, numeric type block_size, numeric type word_size) deriving(Bits,Eq);
+
+ typedef struct{
+ Bit#(TMul#(word_size,8)) data_word;
+ Bit#(1) bus_error;
+ Bit#(1) misaligned_error;
+ Bit#(addr_width) address;
+ Access_type load_store;
+ }To_Cpu_D#(numeric type addr_width,numeric type word_size) deriving(Bits,Eq);
+
+ typedef struct{
+ Bit#(`PADDR) address;
+ Bit#(8) burst_length;
+ Access_type ld_st;
+ Bit#(TLog#(TDiv#(`VADDR, 8))) transfer_size; // 0 -8 bits, 1- 16 bits, 2 -32 bits 3 - 64-bits;
+ Bit#(TMul#(`DCACHE_BLOCK_SIZE,TMul#(`DCACHE_WORD_SIZE,8))) data_line;
+ } To_Memory_Write deriving(Bits,Eq);
+
+ typedef struct{
+ Bit#(TMul#(word_size,8)) data_line;
+ Bit#(1) bus_error;
+ Bit#(1) misaligned_error;
+ Bit#(addr_width) address;
+ }From_Memory_D#(numeric type addr_width,numeric type word_size, numeric type block_size) deriving(Bits,Eq);
+
+
+typedef enum{
+ Taken, Notaken
+}Actual_jump deriving (Eq,Bits,FShow); // actual branch condition used in the branch execution unit.
+
+
+// enum defining the prediction of the branch predictor for the current PC.
+typedef enum{
+ Predicted_taken,Predicted_notaken
+}Prediction_type deriving (Eq,Bits,FShow); // output from the branch prediction unit.
+
+// A typedef defining , if the prediction by the branch predictor was correct or wrong.
+typedef union tagged{
+ Bit#(`VADDR) Mispredicted;
+ Bit#(`VADDR) Correct_prediction;
+}Prediction_result deriving (Eq,Bits,FShow); // result of prediuction from the branch execution unit.
+
+typedef struct{
+ Bit#(addr_width) prog_counter_;
+ Prediction_type prediction_;
+ Bool jump;
+} Predictor_output#(numeric type addr_width) deriving(Bits, Eq); // the program counter from the branch prediction unit.
+
+typedef struct{
+ Bit#(`Reg_width) data_forward;
+ Bit#(TLog#(`PRFDEPTH)) pid;
+}Operand_forwading_type deriving (Bits,Eq); // the data structure for operand forwarding from any stage
+
+typedef union tagged{
+ Bit#(`Reg_width) Data;
+ Bit#(TLog#(`PRFDEPTH)) Pid;
+} FromRf deriving (Bits,Eq,FShow);
+
+typedef struct{
+ Bit#(`Reg_width) rs1;
+ Bit#(`Reg_width) rs2;
+ `ifdef spfpu Bit#(`Reg_width) rs3;`endif
+} Output_for_operand_fetch deriving (Bits,Eq); // output from the register file to the decode stage
+
+typedef enum {
+ ALU,MUL,DIV,MEMORY,BRANCH,JAL,JALR `ifdef spfpu ,DFLOATING,FLOATING `endif ,FENCE,FENCEI,SYSTEM_INSTR,NOP
+}Instruction_type deriving(Bits, Eq,FShow); // the type of the decoded instruction.
+
+// to distuingish between integer and floating point RF
+typedef enum {IntegerRF `ifdef spfpu ,FloatingRF `endif } Register_type deriving(Bits,Eq,FShow);
+typedef enum {IntegerRF `ifdef spfpu ,FloatingRF `endif , Immediate, PC} Operand_type deriving(Bits,Eq,FShow);
+
+
+typedef union tagged{
+ void None;
+ Bit#(`Reg_width) Address;
+ Bit#(`Reg_width) Data;} TriggerType deriving(Bits,Eq,FShow);
+
+typedef struct{
+ TriggerType ttype;
+ Bit#(4) matchscheme;} TriggerData deriving(Bits,Eq,FShow);
+
+// the data stucture for the pipeline FIFO between fetch and decode.
+typedef struct{
+ Bit#(`VADDR) program_counter;
+ Bit#(32) instruction;
+ Trap_type exception;
+ Bit#(`VADDR) nextpc;
+ Bit#(2) prediction;
+ Bit#(`PERFMONITORS) perfmonitors;
+ Bit#(2) epochs;
+}IF_ID_type deriving (Bits,Eq);
+
+typedef struct{
+ Bit#(`Reg_width) rs1;
+ Bit#(`Reg_width) rs2;
+ Bit#(5) rs1_addr;
+ Bit#(12) csr_address;
+ Bit#(3) funct3;
+ }CSRInputs deriving(Bits,Eq,FShow);
+
+typedef struct{
+ Instruction_type inst_type;
+ Operand_type rdtype;
+ Bit#(`Reg_width) rs1;
+ Bit#(`Reg_width) rs2;
+ Bit#(`Reg_width) rs3_imm;
+ Bit#(5) rs1addr;
+ Bit#(5) rs2addr;
+ Bit#(5) rs3addr;
+ Operand_type rs1_type;
+ Operand_type rs2_type;
+ Operand_type rs3_type;
+ Bit#(`VADDR) program_counter;
+ Bool word32;
+ Access_type mem_access;
+ Bit#(4) fn; // TODO Check is this can suffices for memaccess also
+ Trap_type exception;
+ Bit#(5) destination;
+ Bit#(`VADDR) nextpc;
+ Bit#(3) funct3;
+ `ifdef spfpu Bool fcsr_rm; `endif
+ `ifdef simulate Bit#(32) instruction ;`endif
+ Bit#(3) debugcause;
+ Bit#(2) prediction;
+ Bit#(`PERFMONITORS) perfmonitors;
+ Bit#(2) epochs;
+}ID_IE_type deriving (Bits,Eq);
+
+typedef struct{
+ Bit#(`Reg_width) address;
+ Bit#(`Reg_width) memory_data; // data to be written in the memory
+ Bit#(TLog#(TDiv#(`VADDR, 8))) transfer_size; // 0 -8 bits, 1- 16 bits, 2 -32 bits 3 - 64-bits;
+ Bit#(1) signextend; // whether the loaded value has to be signextended
+ Access_type mem_type; // STORE or AMO or LOAD or FENCE
+ `ifdef atomic Bit#(5) atomic_op;`endif
+ Bit#(1) epochs;
+ }Memout deriving(Bits,Eq,FShow);
+
+typedef union tagged{
+ Arithout RESULT; // 64+5
+ Memout MEMORY; // 64+64+3+1+3+5 = 140
+ CSRInputs SYSTEM; // 64+64+5+12+3 = 148
+ void Busy;
+} Execution_output deriving(Bits,Eq,FShow);
+
+//typedef struct{
+// Bit#(`Reg_width) result_addr_rs1;
+// Bit#(`Reg_width) data_rs2;
+// Bit#(20) csr_mem;
+//} Execution_output deriving(Bits,Eq,FShow);
+
+typedef struct{
+ Execution_output execresult;
+ Bit#(`VADDR) program_counter;
+ Trap_type exception;
+ Bit#(5) destination;
+ Operand_type rd_type;
+ Bit#(TLog#(`PRFDEPTH)) index;
+ Bit#(4) pid;
+ `ifdef simulate Bit#(32) instruction ;`endif
+ Bit#(3) debugcause;
+ Bit#(`PERFMONITORS) perfmonitors;
+ Bit#(2) epochs;
+}IE_IMEM_type deriving (Bits,Eq);
+
+typedef struct{
+ Bit#(`Reg_width) aluresult;
+ Bit#(5) fflags;
+ } Arithout deriving(Bits,Eq,FShow); // output struct from the alu.
+
+typedef struct{
+ Bit#(`Reg_width) address;
+ Bit#(3) transfer_size;
+ Access_type load_store;
+ }MemoryResponse deriving(Bits,Eq,FShow);
+
+typedef union tagged{
+ Arithout RESULT;
+ CSRInputs SYSTEM;
+} WriteBackType deriving(Bits,Eq);
+
+typedef struct{
+ WriteBackType commit_data;
+ Bit#(5) destination;
+ Operand_type rd_type;
+ Bit#(TLog#(`PRFDEPTH)) index;
+ Bit#(4) pid;
+ Bit#(`VADDR) program_counter;
+ Trap_type exception;
+ `ifdef simulate Bit#(32) instruction ;`endif
+ Bit#(3) debugcause;
+ Bit#(`PERFMONITORS) perfmonitors;
+ Bit#(2) epochs;
+}IMEM_IWB_type deriving(Bits,Eq);
+
+typedef struct {
+ Bit#(paddr) address;
+ Bit#(TLog#(TDiv#(paddr,8))) transfer_size;
+ Bit#(1) u_signed;
+ Bit#(3) byte_offset;
+ Bit#(TMul#(8, word_size)) write_data;
+ Access_type ld_st;
+} UncachedMemReq#(numeric type paddr, numeric type word_size) deriving(Bits, Eq);
+
+/************************** Interfaces in PLIC ******************************/
+
+interface Ifc_global_interrupt;
+ method Action irq_frm_gateway(Bool ir);
+endinterface
+
+interface Ifc_program_registers#(numeric type addr_width,numeric type word_size);
+ method ActionValue#(Bit#(TMul#(8,word_size))) prog_reg(UncachedMemReq#(addr_width, word_size) mem_req);
+endinterface
+/****************************************************************************/
+
+typedef struct {
+ Bit#(addr_width) pc;
+ Bit#(addr_width) branch_address;
+ Bit#(2) state;} Training_data#(numeric type addr_width) deriving (Bits, Eq);
+
+typedef enum {SWAP,ADD,XOR,AND,OR,MINU,MAXU,MIN,MAX} Atomic_funct deriving(Bits,Eq,FShow);
+
+typedef struct{
+ Bit#(width) final_result; // the final result for the operation
+ Bit#(5) fflags; // indicates if any exception is generated.
+ }Floating_output#(numeric type width) deriving(Bits,Eq); // data structure of the output FIFO.
+
+typedef enum {
+ Inst_addr_misaligned=0,
+ Inst_access_fault=1,
+ Illegal_inst=2,
+ Breakpoint=3,
+ Load_addr_misaligned=4,
+ Load_access_fault=5,
+ Store_addr_misaligned=6,
+ Store_access_fault=7,
+ Ecall_from_user=8,
+ Ecall_from_supervisor=9,
+ Ecall_from_machine=11,
+ Inst_pagefault=12,
+ Load_pagefault=13,
+ Store_pagefault=15
+ `ifdef simulate ,Endsimulation =16 `endif
+} Exception_cause deriving (Bits,Eq,FShow);
+
+typedef struct {
+ Bit#(TSub#(`VADDR,TAdd#(TLog#(`DCACHE_BLOCK_SIZE), TLog#(`DCACHE_WORD_SIZE)))) vtag;
+ Bit#(`DCACHE_TAG_BITS) ptag;
+ Bit#(TLog#(`DCACHE_WAYS)) writeblock;
+ Bit#(1) dirty;
+ Bit#(1) valid;
+} Linebuff_tag deriving (Bits, Eq, FShow);
+typedef enum{
+ /*==== Standard =============== */
+ User_soft_int=0,
+ Supervisor_soft_int=1,
+ Machine_soft_int=3,
+ User_timer_int=4,
+ Supervisor_timer_int=5,
+ Machine_timer_int=7,
+ User_external_int=8,
+ Supervisor_external_int=9,
+ Machine_external_int=11,
+ /*=============================*/
+ /*===== Non Standard========= */
+ DebugInterrupt =12,
+ DebugResume=13,
+ DebugReset=14
+// Icache_miss =12,
+// Icache_cacheable =13,
+// Icache_linereplace =14,
+// Icache_tlbmiss =15,
+// Icache_misaligned =16,
+// Cond_branch =17,
+// Cond_branch_taken =18,
+// Cond_branch_mispredicted =19,
+// Taken_branch_mispredicted =20,
+// Uncond_jumps =21,
+// Spfpu_inst =22,
+// Dpfpu_inst =23,
+// Dcache_tlbmiss =24,
+// Total_loads =25,
+// Total_stores =26,
+// Total_atomic =27,
+// Dcache_load_miss =28,
+// Dcache_store_miss =29,
+// Dcache_atomic_miss =30,
+// Dcache_cacheable_load =31,
+// Dcache_cacheable_store =32,
+// Dcache_cacheable_atomic =33,
+// Dcache_writebacks =34,
+// Dcache_linereplace =35,
+// Dcache_misaligned =36,
+// Exceptions_taken =37,
+// Interrupts_taken =38,
+// Muldiv_instructions =39,
+// System_instructions =40,
+// Usermode_cycles =41,
+// Supervisormode_cycles =42,
+// Machinemode_cyles =43,
+// Misprediction_stalls =44,
+// Interrupt_stalls =45,
+// Dfence_cycles =46,
+// Ifence_cycles =47,
+// Dcache_miss_cycles =48,
+// Icache_miss_cycles =49,
+// Fpbusy_cycles =50,
+// Divisionbusy_cycles =51,
+// Total_stall_cycles =52,
+// Pagewalk_cycles =53,
+// Corebus_cycles =54
+} Interrupt_cause deriving (Bits,Eq,FShow);
+
+typedef union tagged{
+ Exception_cause Exception;
+ Interrupt_cause Interrupt;
+ void None;
+} Trap_type deriving(Bits,Eq,FShow);
+
+function String event_name(Bit#(64) eventnum);
+ case (eventnum)
+ 'h0000000000000001: return "ICACHE_MISS ";
+ 'h0000000000000002: return "ICACHE_CACHEABLE ";
+ 'h0000000000000004: return "ICACHE_LINEREPLACE ";
+ 'h0000000000000008: return "ICACHE_TLBMISS ";
+ 'h0000000000000010: return "ICACHE_MISALIGNED ";
+ 'h0000000000000020: return "ICACHE_PREFETCHMISS ";
+ 'h0000000000000040: return "COND_BRANCH ";
+ 'h0000000000000080: return "COND_BRANCH_TAKEN ";
+ 'h0000000000000100: return "COND_BRANCH_MISPREDICTED ";
+ 'h0000000000000200: return "TAKEN_BRANCH_MISPREDICTED ";
+ 'h0000000000000400: return "UNCOND_JUMPS ";
+ 'h0000000000000800: return "SPFPU_INST ";
+ 'h0000000000001000: return "DPFPU_INST ";
+ 'h0000000000002000: return "DCACHE_TLBMISS ";
+ 'h0000000000004000: return "TOTAL_LOADS ";
+ 'h0000000000008000: return "TOTAL_STORES ";
+ 'h0000000000010000: return "TOTAL_ATOMIC ";
+ 'h0000000000020000: return "DCACHE_LOAD_MISS ";
+ 'h0000000000040000: return "DCACHE_STORE_MISS ";
+ 'h0000000000080000: return "DCACHE_ATOMIC_MISS ";
+ 'h0000000000100000: return "DCACHE_CACHEABLE_LOAD ";
+ 'h0000000000200000: return "DCACHE_CACHEABLE_STORE ";
+ 'h0000000000400000: return "DCACHE_CACHEABLE_ATOMIC ";
+ 'h0000000000800000: return "DCACHE_WRITEBACKS ";
+ 'h0000000001000000: return "DCACHE_LINEREPLACE ";
+ 'h0000000002000000: return "DCACHE_MISALIGNED ";
+ 'h0000000004000000: return "EXCEPTIONS_TAKEN ";
+ 'h0000000008000000: return "INTERRUPTS_TAKEN ";
+ 'h0000000010000000: return "MULDIV_INSTRUCTIONS ";
+ 'h0000000020000000: return "MEMORY_INSTRUCTIONS ";
+ 'h0000000040000000: return "EXEC_FLUSHES ";
+ 'h0000000080000000: return "WB_FLUSHES ";
+ default: return "NO EVENT";
+ endcase
+endfunction
+
+/****************************** MMU TYPES *******************************/
+
+typedef struct {
+ bit mprv;
+ bit sum;
+ bit mxr;
+ Privilege_mode mpp;
+ Privilege_mode prv;
+} Chmod deriving(Bits, Eq);
+
+typedef struct {
+ bit v; //valid
+ bit r; //allow reads
+ bit w; //allow writes
+ bit x; //allow execute(instruction read)
+ bit u; //allow supervisor
+ bit g; //global page
+ bit a; //accessed already
+ bit d; //dirty
+} TLB_permissions deriving(Bits, Eq, FShow);
+
+typedef struct {
+ Bit#(TSub#(paddr,page_size)) ppn;
+ TLB_permissions tlb_perm;
+ Bit#(asid_width) asid;
+ Bit#(2) levels;
+} To_TLB#(numeric type paddr, numeric type page_size, numeric type asid_width) deriving(Bits,Eq);
+
+typedef struct {
+ Bit#(data_width) vaddr;
+ Access_type ld_st_atomic;
+} DTLB_access#(numeric type data_width) deriving(Bits, Eq);
+
+typedef enum {
+ PTW_ready, Handling_PTW, Wait_for_memory, PTW_done, Send_to_memory} PTW_state deriving(Bits, Eq);
+
+typedef enum {
+ Load, Store, Execution} Translation_type deriving(Bits, Eq);
+
+typedef struct {
+ Translation_type page_type;
+ Bit#(TSub#(vaddr_width,page_offset)) vpn;
+} Request_PPN_PTW#(numeric type vaddr_width, numeric type page_offset) deriving (Bits,Eq);
+
+typedef struct {
+ Translation_type page_type;
+ To_TLB#(paddr_width,page_offset,asid_width) tlb_packet;
+} Response_PPN_TLB#(numeric type paddr_width, numeric type page_offset, numeric type asid_width) deriving (Bits,Eq);
+
+typedef struct {
+ Bool ptwdone;
+ Translation_type page_type;
+ Bit#(data_width) address;
+} Request_PTE_memory#(numeric type data_width) deriving (Bits,Eq);
+
+typedef struct {
+ Trap_type exception;
+ Bit#(data_width) address;
+ Bool cacheable;
+} From_TLB#(numeric type data_width) deriving (Bits, Eq);
+
+typedef struct {
+ Bit#(vaddr_width) rs1;
+ Bit#(vaddr_width) rs2;
+} Fence_VMA_type#(numeric type vaddr_width) deriving (Bits, Eq);
+
+typedef enum {
+ Store_pf, Load_pf, Instruction_pf, None} Pf_exception_type deriving (Bits, Eq);
+/*=============================================================================== */
+
+/* =============================== Debug related types ========================== */
+typedef enum {CPU_CONTINUE,CPU_STOPPED} CPU_State deriving(Bits,Eq,FShow);
+typedef enum {
+ GDB_INTERRUPT,
+ GDB_HUP,
+ GDB_INT,
+ GDB_QUIT,
+ GDB_ILL,
+ GDB_BREAK = 5,
+ CPU_BUSY
+ } GdbStopCondition
+deriving (Bits ,Eq, FShow);
+
+/*======= AXI4 master/slave numbers ======*/
+typedef 0 Sdram_slave_num;
+typedef TAdd#(Sdram_slave_num ,`ifdef SDRAM 1 `else 0 `endif ) Sdram_cfg_slave_num;
+typedef TAdd#(Sdram_cfg_slave_num,`ifdef BOOTROM 1 `else 0 `endif ) BootRom_slave_num ;
+typedef TAdd#(BootRom_slave_num ,`ifdef Debug 1 `else 0 `endif ) Debug_slave_num ;
+typedef TAdd#(Debug_slave_num , `ifdef TCMemory 1 `else 0 `endif ) TCM_slave_num;
+typedef TAdd#(TCM_slave_num ,`ifdef DMA 1 `else 0 `endif ) Dma_slave_num;
+typedef TAdd#(Dma_slave_num ,1 ) SlowPeripheral_slave_num;
+typedef TAdd#(SlowPeripheral_slave_num,`ifdef VME 1 `else 0 `endif ) VME_slave_num;
+typedef TAdd#(VME_slave_num,`ifdef FlexBus 1 `else 0 `endif ) FlexBus_slave_num;
+typedef TAdd#(FlexBus_slave_num,1) Num_Slaves;
+typedef 0 Dmem_master_num;
+typedef 1 Imem_master_num;
+typedef TAdd#(Imem_master_num , `ifdef Debug 1 `else 0 `endif ) Debug_master_num;
+typedef TAdd#(Debug_master_num, `ifdef DMA 1 `else 0 `endif ) DMA_master_num;
+typedef TAdd#(DMA_master_num,1) Num_Masters;
+
+/*=============================================================================== */
+/*====== AXI4 Lite slave declarations =======*/
+typedef 0 SlowMaster;
+typedef 0 Uart0_slave_num ;
+typedef TAdd#(Uart0_slave_num ,`ifdef UART1 1 `else 0 `endif )
+ Uart1_slave_num ;
+typedef TAdd#(Uart1_slave_num ,`ifdef CLINT 1 `else 0 `endif )
+ CLINT_slave_num;
+typedef TAdd#(CLINT_slave_num ,`ifdef PLIC 1 `else 0 `endif )
+ Plic_slave_num ;
+typedef TAdd#(Plic_slave_num ,`ifdef PLIC 1 `else 0 `endif )
+ GPIO_slave_num ;
+typedef TAdd#(GPIO_slave_num ,`ifdef I2C0 1 `else 0 `endif )
+ I2c0_slave_num ;
+typedef TAdd#(I2c0_slave_num ,`ifdef I2C1 1 `else 0 `endif )
+ I2c1_slave_num ;
+typedef TAdd#(I2c1_slave_num ,`ifdef QSPI0 1 `else 0 `endif )
+ Qspi0_slave_num ;
+typedef TAdd#(Qspi0_slave_num ,`ifdef QSPI1 1 `else 0 `endif )
+ Qspi1_slave_num ;
+typedef TAdd#(Qspi1_slave_num ,`ifdef AXIEXP 1 `else 0 `endif )
+ AxiExp1_slave_num;
+typedef TAdd#(AxiExp1_slave_num ,`ifdef PWM_AXI4Lite 1 `else 0 `endif )
+ Pwm_slave_num;
+typedef TAdd#(Pwm_slave_num,1) Muxa_slave_num;
+typedef TAdd#(Muxa_slave_num,1) Gpioa_slave_num;
+typedef TAdd#(Gpioa_slave_num,1) Num_Slow_Slaves;
+
+/*===========================================*/
+
+endpackage
temp[i]=pack(direction_reg[i]);
return temp;
endmethod
- endinterface
+ endinterface;
interface pad_config=interface GPIO_config
method Vector#(ionum,Bit#(1)) gpio_DRV0;
Vector#(ionum,Bit#(1)) temp;
`define DATA 64
`define USERSPACE 0
`define PADDR 32
-`define Reg_width 32
-`define PWM_AXI4Lite enable
+`define Reg_width 64
+`define PRFDEPTH 6
+`define VADDR 39
+`define DCACHE_BLOCK_SIZE 4
+`define DCACHE_WORD_SIZE 8
+`define PERFMONITORS 64
+`define DCACHE_WAYS 4
+`define DCACHE_TAG_BITS 20 // tag_bits = 52
+
+
+//`define PWM_AXI4Lite enable
--- /dev/null
+
+/*
+ This BSV file has been generated by the PinMux tool available at:
+ https://bitbucket.org/casl/pinmux.
+
+ Authors: Neel Gala, Luke
+ Date of generation: Mon Jul 16 12:11:50 2018
+*/
+
+package pinmux;
+
+ interface MuxSelectionLines;
+
+ // declare the method which will capture the user pin-mux
+ // selection values.The width of the input is dependent on the number
+ // of muxes happening per IO. For now we have a generalized width
+ // where each IO will have the same number of muxes.
+ method Action cell0_mux (Bit#(2) in);
+ method Action cell1_mux (Bit#(2) in);
+ method Action cell2_mux (Bit#(2) in);
+ endinterface
+
+
+ interface IOCellSide;
+ // declare the interface to the IO cells.
+ // Each IO cell will have 1 input field (output from pin mux)
+ // and an output and out-enable field (input to pinmux)
+ // interface declaration between IO-0 and pinmux
+ (*always_ready,always_enabled*) method Bit#(1) io0_cell_out;
+ (*always_ready,always_enabled*) method Bit#(1) io0_cell_outen;
+ (*always_ready,always_enabled,result="io"*) method
+ Action io0_cell_in (Bit#(1) in);
+ // interface declaration between IO-1 and pinmux
+ (*always_ready,always_enabled*) method Bit#(1) io1_cell_out;
+ (*always_ready,always_enabled*) method Bit#(1) io1_cell_outen;
+ (*always_ready,always_enabled,result="io"*) method
+ Action io1_cell_in (Bit#(1) in);
+ // interface declaration between IO-2 and pinmux
+ (*always_ready,always_enabled*) method Bit#(1) io2_cell_out;
+ (*always_ready,always_enabled*) method Bit#(1) io2_cell_outen;
+ (*always_ready,always_enabled,result="io"*) method
+ Action io2_cell_in (Bit#(1) in);
+ endinterface
+
+
+ interface PeripheralSide;
+ // declare the interface to the peripherals
+ // Each peripheral's function will be either an input, output
+ // or be bi-directional. an input field will be an output from the
+ // peripheral and an output field will be an input to the peripheral.
+ // Bi-directional functions also have an output-enable (which
+ // again comes *in* from the peripheral)
+ // interface declaration between UART-0 and pinmux
+ (*always_ready,always_enabled*) method Action uart_tx (Bit#(1) in);
+ (*always_ready,always_enabled*) method Bit#(1) uart_rx;
+ // interface declaration between GPIOA-0 and pinmux
+ (*always_ready,always_enabled*) method Action gpioa_a0_out (Bit#(1) in);
+ (*always_ready,always_enabled*) method Action gpioa_a0_outen (Bit#(1) in);
+ (*always_ready,always_enabled*) method Bit#(1) gpioa_a0_in;
+ (*always_ready,always_enabled*) method Action gpioa_a1_out (Bit#(1) in);
+ (*always_ready,always_enabled*) method Action gpioa_a1_outen (Bit#(1) in);
+ (*always_ready,always_enabled*) method Bit#(1) gpioa_a1_in;
+ (*always_ready,always_enabled*) method Action gpioa_a2_out (Bit#(1) in);
+ (*always_ready,always_enabled*) method Action gpioa_a2_outen (Bit#(1) in);
+ (*always_ready,always_enabled*) method Bit#(1) gpioa_a2_in;
+ // interface declaration between TWI-0 and pinmux
+ (*always_ready,always_enabled*) method Action twi_sda_out (Bit#(1) in);
+ (*always_ready,always_enabled*) method Action twi_sda_outen (Bit#(1) in);
+ (*always_ready,always_enabled*) method Bit#(1) twi_sda_in;
+ (*always_ready,always_enabled*) method Action twi_scl_out (Bit#(1) in);
+ (*always_ready,always_enabled*) method Action twi_scl_outen (Bit#(1) in);
+ (*always_ready,always_enabled*) method Bit#(1) twi_scl_in;
+ endinterface
+
+
+ interface Ifc_pinmux;
+ // this interface controls how each IO cell is routed. setting
+ // any given IO cell's mux control value will result in redirection
+ // of not just the input or output to different peripheral functions
+ // but also the *direction* control - if appropriate - as well.
+ interface MuxSelectionLines mux_lines;
+
+ // this interface contains the inputs, outputs and direction-control
+ // lines for all peripherals. GPIO is considered to also be just
+ // a peripheral because it also has in, out and direction-control.
+ interface PeripheralSide peripheral_side;
+
+ // this interface is to be linked to the individual IO cells.
+ // if looking at a "non-muxed" GPIO design, basically the
+ // IO cell input, output and direction-control wires are cut
+ // (giving six pairs of dangling wires, named left and right)
+ // these iocells are routed in their place on one side ("left")
+ // and the matching *GPIO* peripheral interfaces in/out/dir
+ // connect to the OTHER side ("right"). the result is that
+ // the muxer settings end up controlling the routing of where
+ // the I/O from the IOcell actually goes.
+ interface IOCellSide iocell_side;
+ endinterface
+ (*synthesize*)
+ module mkpinmux(Ifc_pinmux);
+
+ // the followins wires capture the pin-mux selection
+ // values for each mux assigned to a CELL
+
+ Wire#(Bit#(2)) wrcell0_mux<-mkDWire(0);
+ Wire#(Bit#(2)) wrcell1_mux<-mkDWire(0);
+ Wire#(Bit#(2)) wrcell2_mux<-mkDWire(0);
+ // following wires capture signals to IO CELL if io-0 is
+ // allotted to it
+ Wire#(Bit#(1)) cell0_mux_out<-mkDWire(0);
+ Wire#(Bit#(1)) cell0_mux_outen<-mkDWire(0);
+ Wire#(Bit#(1)) cell0_mux_in<-mkDWire(0);
+
+ // following wires capture signals to IO CELL if io-1 is
+ // allotted to it
+ Wire#(Bit#(1)) cell1_mux_out<-mkDWire(0);
+ Wire#(Bit#(1)) cell1_mux_outen<-mkDWire(0);
+ Wire#(Bit#(1)) cell1_mux_in<-mkDWire(0);
+
+ // following wires capture signals to IO CELL if io-2 is
+ // allotted to it
+ Wire#(Bit#(1)) cell2_mux_out<-mkDWire(0);
+ Wire#(Bit#(1)) cell2_mux_outen<-mkDWire(0);
+ Wire#(Bit#(1)) cell2_mux_in<-mkDWire(0);
+
+ // following wires capture signals to IO CELL if uart-0 is
+ // allotted to it
+ Wire#(Bit#(1)) wruart_tx<-mkDWire(0);
+ Wire#(Bit#(1)) wruart_rx<-mkDWire(0);
+
+ // following wires capture signals to IO CELL if gpioa-0 is
+ // allotted to it
+ Wire#(Bit#(1)) wrgpioa_a0_out<-mkDWire(0);
+ Wire#(Bit#(1)) wrgpioa_a0_outen<-mkDWire(0);
+ Wire#(Bit#(1)) wrgpioa_a0_in<-mkDWire(0);
+ Wire#(Bit#(1)) wrgpioa_a1_out<-mkDWire(0);
+ Wire#(Bit#(1)) wrgpioa_a1_outen<-mkDWire(0);
+ Wire#(Bit#(1)) wrgpioa_a1_in<-mkDWire(0);
+ Wire#(Bit#(1)) wrgpioa_a2_out<-mkDWire(0);
+ Wire#(Bit#(1)) wrgpioa_a2_outen<-mkDWire(0);
+ Wire#(Bit#(1)) wrgpioa_a2_in<-mkDWire(0);
+
+ // following wires capture signals to IO CELL if twi-0 is
+ // allotted to it
+ Wire#(Bit#(1)) wrtwi_sda_out<-mkDWire(0);
+ Wire#(Bit#(1)) wrtwi_sda_outen<-mkDWire(0);
+ Wire#(Bit#(1)) wrtwi_sda_in<-mkDWire(0);
+ Wire#(Bit#(1)) wrtwi_scl_out<-mkDWire(0);
+ Wire#(Bit#(1)) wrtwi_scl_outen<-mkDWire(0);
+ Wire#(Bit#(1)) wrtwi_scl_in<-mkDWire(0);
+
+
+ /*====== This where the muxing starts for each io-cell======*/
+ Wire#(Bit#(1)) val0<-mkDWire(0); // need a zero
+ // output muxer for cell idx 0
+ cell0_mux_out=
+ wrcell0_mux==0?wrgpioa_a0_out:
+ wrcell0_mux==1?wruart_tx:
+ wrcell0_mux==2?val0: // unused
+ wrtwi_sda_out;
+
+ // outen muxer for cell idx 0
+ cell0_mux_outen=
+ wrcell0_mux==0?wrgpioa_a0_outen: // bi-directional
+ wrcell0_mux==1?wrgpioa_a0_outen: // uart_tx is an output
+ wrcell0_mux==2?val0: // unused
+ wrtwi_sda_outen; // bi-directional
+
+ // priority-in-muxer for cell idx 0
+ rule assign_wrgpioa_a0_in_on_cell0(wrcell0_mux==0);
+ wrgpioa_a0_in<=cell0_mux_in;
+ endrule
+
+ rule assign_wrtwi_sda_in_on_cell0(wrcell0_mux==3);
+ wrtwi_sda_in<=cell0_mux_in;
+ endrule
+
+ // output muxer for cell idx 1
+ cell1_mux_out=
+ wrcell1_mux==0?wrgpioa_a1_out:
+ wrcell1_mux==1?val0: // uart_rx is an input
+ wrcell1_mux==2?wrtwi_sda_out:
+ val0; // unused
+
+ // outen muxer for cell idx 1
+ cell1_mux_outen=
+ wrcell1_mux==0?wrgpioa_a1_outen: // bi-directional
+ wrcell1_mux==1?val0: // uart_rx is an input
+ wrcell1_mux==2?wrtwi_sda_outen: // bi-directional
+ val0; // unused
+
+ // priority-in-muxer for cell idx 1
+ rule assign_wrgpioa_a1_in_on_cell1(wrcell1_mux==0);
+ wrgpioa_a1_in<=cell1_mux_in;
+ endrule
+
+ rule assign_wruart_rx_on_cell1(wrcell1_mux==1);
+ wruart_rx<=cell1_mux_in;
+ endrule
+
+ rule assign_wrtwi_sda_in_on_cell1(wrcell1_mux==2);
+ wrtwi_sda_in<=cell1_mux_in;
+ endrule
+
+ // output muxer for cell idx 2
+ cell2_mux_out=
+ wrcell2_mux==0?wrgpioa_a2_out:
+ wrcell2_mux==1?val0: // unused
+ wrcell2_mux==2?wrtwi_scl_out:
+ val0; // unused
+
+ // outen muxer for cell idx 2
+ cell2_mux_outen=
+ wrcell2_mux==0?wrgpioa_a2_outen: // bi-directional
+ wrcell2_mux==1?val0: // unused
+ wrcell2_mux==2?wrtwi_scl_outen: // bi-directional
+ val0; // unused
+
+ // priority-in-muxer for cell idx 2
+ rule assign_wrgpioa_a2_in_on_cell2(wrcell2_mux==0);
+ wrgpioa_a2_in<=cell2_mux_in;
+ endrule
+
+ rule assign_wrtwi_scl_in_on_cell2(wrcell2_mux==2);
+ wrtwi_scl_in<=cell2_mux_in;
+ endrule
+
+
+ /*=========================================*/
+ // dedicated cells
+
+
+ /*============================================================*/
+
+ interface mux_lines = interface MuxSelectionLines
+
+ method Action cell0_mux(Bit#(2) in);
+ wrcell0_mux<=in;
+ endmethod
+
+ method Action cell1_mux(Bit#(2) in);
+ wrcell1_mux<=in;
+ endmethod
+
+ method Action cell2_mux(Bit#(2) in);
+ wrcell2_mux<=in;
+ endmethod
+
+ endinterface;
+ interface iocell_side = interface IOCellSide
+
+ method io0_cell_out=cell0_mux_out;
+ method io0_cell_outen=cell0_mux_outen;
+ method Action io0_cell_in(Bit#(1) in);
+ cell0_mux_in<=in;
+ endmethod
+
+ method io1_cell_out=cell1_mux_out;
+ method io1_cell_outen=cell1_mux_outen;
+ method Action io1_cell_in(Bit#(1) in);
+ cell1_mux_in<=in;
+ endmethod
+
+ method io2_cell_out=cell2_mux_out;
+ method io2_cell_outen=cell2_mux_outen;
+ method Action io2_cell_in(Bit#(1) in);
+ cell2_mux_in<=in;
+ endmethod
+
+ endinterface;
+ interface peripheral_side = interface PeripheralSide
+
+ method Action uart_tx(Bit#(1) in);
+ wruart_tx<=in;
+ endmethod
+ method uart_rx=wruart_rx;
+
+ method Action gpioa_a0_out(Bit#(1) in);
+ wrgpioa_a0_out<=in;
+ endmethod
+ method Action gpioa_a0_outen(Bit#(1) in);
+ wrgpioa_a0_outen<=in;
+ endmethod
+ method gpioa_a0_in=wrgpioa_a0_in;
+ method Action gpioa_a1_out(Bit#(1) in);
+ wrgpioa_a1_out<=in;
+ endmethod
+ method Action gpioa_a1_outen(Bit#(1) in);
+ wrgpioa_a1_outen<=in;
+ endmethod
+ method gpioa_a1_in=wrgpioa_a1_in;
+ method Action gpioa_a2_out(Bit#(1) in);
+ wrgpioa_a2_out<=in;
+ endmethod
+ method Action gpioa_a2_outen(Bit#(1) in);
+ wrgpioa_a2_outen<=in;
+ endmethod
+ method gpioa_a2_in=wrgpioa_a2_in;
+
+ method Action twi_sda_out(Bit#(1) in);
+ wrtwi_sda_out<=in;
+ endmethod
+ method Action twi_sda_outen(Bit#(1) in);
+ wrtwi_sda_outen<=in;
+ endmethod
+ method twi_sda_in=wrtwi_sda_in;
+ method Action twi_scl_out(Bit#(1) in);
+ wrtwi_scl_out<=in;
+ endmethod
+ method Action twi_scl_outen(Bit#(1) in);
+ wrtwi_scl_outen<=in;
+ endmethod
+ method twi_scl_in=wrtwi_scl_in;
+
+ endinterface;
+ endmodule
+endpackage
+++ /dev/null
-package slow_peripherals;
- /*===== Project imports =====*/
- import defined_types::*;
- import AXI4_Lite_Fabric::*;
- import AXI4_Lite_Types::*;
- import AXI4_Fabric::*;
- import AXI4_Types::*;
- import Semi_FIFOF::*;
- import AXI4Lite_AXI4_Bridge::*;
- `include "defined_parameters.bsv"
- /*===========================*/
- /*=== package imports ===*/
- import Clocks::*;
- import GetPut::*;
- import ClientServer::*;
- import Connectable::*;
- import Vector::*;
- import FIFO::*;
- /*=======================*/
- /*===== Import the slow peripherals ====*/
- `ifdef UART0
- import Uart16550 :: *;
- `endif
- `ifdef UART1
- import Uart_bs::*;
- import RS232_modified::*;
- `endif
- `ifdef CLINT
- import clint::*;
- `endif
- `ifdef PLIC
- import gpio ::*;
- import plic ::*;
- `endif
- `ifdef I2C0
- import I2C_top :: *;
- `endif
- `ifdef QSPI0
- import qspi :: *;
- `endif
- `ifdef AXIEXP
- import axiexpansion ::*;
- `endif
- `ifdef PWM_AXI4Lite
- import pwm::*;
- `endif
- // NEEL EDIT
- import pinmux::*;
- import mux::*;
- /*=====================================*/
-
- /*===== interface declaration =====*/
- interface SP_ios;
- `ifdef UART0
- interface RS232_PHY_Ifc uart0_coe;
- `endif
- `ifdef UART1
- interface RS232 uart1_coe;
- `endif
- `ifdef PLIC
- (*always_ready,always_enabled*)
- method Action gpio_in (Vector#(`IONum,Bit#(1)) inp);
- (*always_ready,always_enabled*)
- method Vector#(`IONum,Bit#(1)) gpio_out;
- (*always_ready,always_enabled*)
- method Vector#(`IONum,Bit#(1)) gpio_out_en;
- `endif
- `ifdef I2C0
- interface I2C_out i2c0_out;
- `endif
- `ifdef I2C1
- interface I2C_out i2c1_out;
- `endif
- `ifdef QSPI0
- interface QSPI_out qspi0_out;
- `endif
- `ifdef QSPI1
- interface QSPI_out qspi1_out;
- `endif
- `ifdef AXIEXP
- interface Get#(Bit#(67)) axiexp1_out;
- interface Put#(Bit#(67)) axiexp1_in;
- `endif
- `ifdef PWM_AXI4Lite
- interface PWMIO pwm_o;
- `endif
- endinterface
- interface Ifc_slow_peripherals;
- interface AXI4_Slave_IFC#(`PADDR,`Reg_width,`USERSPACE) axi_slave;
- interface SP_ios slow_ios;
- `ifdef CLINT
- method Bit#(1) msip_int;
- method Bit#(1) mtip_int;
- method Bit#(`Reg_width) mtime;
- `endif
- `ifdef PLIC method ActionValue#(Tuple2#(Bool,Bool)) intrpt_note; `endif
- `ifdef I2C0 method Bit#(1) i2c0_isint; `endif
- `ifdef I2C1 method Bit#(1) i2c1_isint; `endif
- `ifdef QSPI0 method Bit#(1) qspi0_isint; `endif
- `ifdef QSPI1 method Bit#(1) qspi1_isint; `endif
- `ifdef UART0 method Bit#(1) uart0_intr; `endif
- // NEEL EDIT
- interface IOCellSide iocell_side; // mandatory interface
- interface GPIO_config#(3) pad_configa; // depends on the number of banks
- // NEEL EDIT OVER
- endinterface
- /*================================*/
-
- function Tuple2#(Bool, Bit#(TLog#(Num_Slow_Slaves))) fn_address_mapping (Bit#(`PADDR) addr);
- `ifdef UART0
- if(addr>=`UART0Base && addr<=`UART0End)
- return tuple2(True,fromInteger(valueOf(Uart0_slave_num)));
- else
- `endif
- `ifdef UART1
- if(addr>=`UART1Base && addr<=`UART1End)
- return tuple2(True,fromInteger(valueOf(Uart1_slave_num)));
- else
- `endif
- `ifdef CLINT
- if(addr>=`ClintBase && addr<=`ClintEnd)
- return tuple2(True,fromInteger(valueOf(CLINT_slave_num)));
- else
- `endif
- `ifdef PLIC
- if(addr>=`PLICBase && addr<=`PLICEnd)
- return tuple2(True,fromInteger(valueOf(Plic_slave_num)));
- else if(addr>=`GPIOBase && addr<=`GPIOEnd)
- return tuple2(True,fromInteger(valueOf(GPIO_slave_num)));
- else
- `endif
- `ifdef I2C0
- if(addr>=`I2C0Base && addr<=`I2C0End)
- return tuple2(True,fromInteger(valueOf(I2c0_slave_num)));
- else
- `endif
- `ifdef I2C1
- if(addr>=`I2C1Base && addr<=`I2C1End)
- return tuple2(True,fromInteger(valueOf(I2c1_slave_num)));
- else
- `endif
- `ifdef QSPI0
- if(addr>=`QSPI0CfgBase && addr<=`QSPI0CfgEnd)
- return tuple2(True,fromInteger(valueOf(Qspi0_slave_num)));
- else if(addr>=`QSPI0MemBase && addr<=`QSPI0MemEnd)
- return tuple2(True,fromInteger(valueOf(Qspi0_slave_num)));
- else
- `endif
- `ifdef QSPI1
- if(addr>=`QSPI1CfgBase && addr<=`QSPI1CfgEnd)
- return tuple2(True,fromInteger(valueOf(Qspi1_slave_num)));
- else if(addr>=`QSPI1MemBase && addr<=`QSPI1MemEnd)
- return tuple2(True,fromInteger(valueOf(Qspi1_slave_num)));
- else
- `endif
- `ifdef AXIEXP
- if(addr>=`AxiExp1Base && addr<=`AxiExp1End)
- return tuple2(True,fromInteger(valueOf(AxiExp1_slave_num)));
- else
- `endif
- `ifdef PWM_AXI4Lite
- if(addr>=`PWMBase && addr<=`PWMEnd)
- return tuple2(True,fromInteger(valueOf(Pwm_slave_num)));
- else
- `endif
-
- // NEEL EDIT
- // give slave number and adress map to whatever peripherals you instantiate on the AXI4_Lite
- // slave.
- // NEEL EDIT OVER
- return tuple2(False,?);
- endfunction
-
- (*synthesize*)
- module mkslow_peripherals#(Clock fast_clock, Reset fast_reset, Clock uart_clock, Reset uart_reset
- `ifdef PWM_AXI4Lite ,Clock ext_pwm_clock `endif )(Ifc_slow_peripherals);
- Clock sp_clock <-exposeCurrentClock; // slow peripheral clock
- Reset sp_reset <-exposeCurrentReset; // slow peripheral reset
-
- /*======= Module declarations for each peripheral =======*/
- `ifdef UART0
- Uart16550_AXI4_Lite_Ifc uart0 <- mkUart16550(clocked_by uart_clock, reset_by uart_reset, sp_clock, sp_reset);
- `endif
- `ifdef UART1
- Ifc_Uart_bs uart1 <- mkUart_bs(clocked_by uart_clock, reset_by uart_reset,sp_clock, sp_reset);
- `endif
- `ifdef CLINT
- Ifc_clint clint <- mkclint();
- `endif
- `ifdef PLIC
- Ifc_PLIC_AXI plic <- mkplicperipheral();
- Wire#(Bit#(TLog#(`INTERRUPT_PINS))) interrupt_id <- mkWire();
- Vector#(`INTERRUPT_PINS, FIFO#(bit)) ff_gateway_queue <- replicateM(mkFIFO);
- GPIO gpio <- mkgpio;
- `endif
- `ifdef I2C0
- I2C_IFC i2c0 <- mkI2CController();
- `endif
- `ifdef I2C1
- I2C_IFC i2c1 <- mkI2CController();
- `endif
- `ifdef QSPI0
- Ifc_qspi qspi0 <- mkqspi();
- `endif
- `ifdef QSPI1
- Ifc_qspi qspi1 <- mkqspi();
- `endif
- `ifdef AXIEXP
- Ifc_AxiExpansion axiexp1 <- mkAxiExpansion();
- `endif
- `ifdef PWM_AXI4Lite
- Ifc_PWM_bus pwm_bus <- mkPWM_bus(ext_pwm_clock);
- `endif
- // NEEL EDIT
- Ifc_pinmux pinmux <- mkpinmux; // mandatory
- MUX#(3) mymux <- mkmux(); // mandatory. number depends on the number of instances required.
- GPIO#(3) mygpioa <- mkgpio(); // optional. depends the number of IO pins declared before.
- // NEEL EDIT OVER
- /*=======================================================*/
-
- AXI4_Lite_Fabric_IFC #(1, Num_Slow_Slaves, `PADDR, `Reg_width,`USERSPACE) slow_fabric <-
- mkAXI4_Lite_Fabric(fn_address_mapping);
- Ifc_AXI4Lite_AXI4_Bridge bridge <-mkAXI4Lite_AXI4_Bridge(fast_clock,fast_reset);
-
- mkConnection (bridge.axi4_lite_master, slow_fabric.v_from_masters [0]);
- /*======= Slave connections to AXI4Lite fabric =========*/
- `ifdef UART0
- mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(Uart0_slave_num))],
- uart0.slave_axi_uart);
- `endif
- `ifdef UART1
- mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(Uart1_slave_num))],
- uart1.slave_axi_uart);
- `endif
- `ifdef CLINT
- mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(CLINT_slave_num))],
- clint.axi4_slave);
- `endif
- `ifdef PLIC
- mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(Plic_slave_num))],
- plic.axi4_slave_plic); //
- mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(GPIO_slave_num))],
- gpio.axi_slave); //
- `endif
- `ifdef I2C0
- mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(I2c0_slave_num))],
- i2c0.slave_i2c_axi);
- `endif
- `ifdef I2C1
- mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(I2c1_slave_num))],
- i2c1.slave_i2c_axi); //
- `endif
- `ifdef QSPI0
- mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(Qspi0_slave_num))],
- qspi0.slave);
- `endif
- `ifdef QSPI1
- mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(Qspi1_slave_num))],
- qspi1.slave);
- `endif
- `ifdef AXIEXP
- mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(AxiExp1_slave_num))],
- axiexp1.axi_slave); //
- `endif
- `ifdef PWM_AXI4Lite
- mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(Pwm_slave_num))],
- pwm_bus.axi4_slave);
- `endif
-
- // NEEL EDIT
- mkConnection (slow_fabric.v_from_masters[/* mux slave number*/], mymux.axi_slave);
- mkConnection (slow_fabric.v_from_masters[/* gpioslave number*/], gpioa.axi_slave);
- rule connect_select_lines_pinmux;// mandatory
- pinmux.cell0_mux(mymux.mux_config[0]);
- pinmux.cell1_mux(mymux.mux_config[1]);
- pinmux.cell2_mux(mymux.mux_config[2]);
- endrule
- rule connect_uart1tx;
- pinmux.peripheral_side.uart_tx(uart1.coe_rs232.rs232.sout);
- endrule
- rule connect_uart1rx;
- uart1.coe_rs232.rs232.sin(pinmux.peripheral_side.uart_rx);
- endrule
- rule connect_gpioa
- pinmux.peripheral_side.gpioa_a0_out(gpio.func.gpio_out[0]);
- pinmux.peripheral_side.gpioa_a0_outen(gpio.func.gpio_out_en[0]);
- Vector#(3,Bit#(1)) temp;
- temp[0]=pinmux.peripheral_side.gpioa_a0_in;
- temp[1]=pinmux.peripheral_side.gpioa_a1_in;
- temp[2]=pinmux.peripheral_side.gpioa_a2_in;
- gpio.pad_config.gpio_in(temp);
- endrule
- // NEEL EDIT OVER
- /*=======================================================*/
- /*=================== PLIC Connections ==================== */
- `ifdef PLIC
- /*TODO DMA interrupt need to be connected to the plic
- for(Integer i=1; i<8; i=i+1) begin
- `ifdef DMA
- rule rl_connect_dma_interrupts_to_plic;
- if(dma.interrupt_to_processor[i-1]==1'b1) begin
- ff_gateway_queue[i].enq(1);
- plic.ifc_external_irq[i].irq_frm_gateway(True);
- end
- endrule
- `else
- rule rl_connect_dma_interrupts_to_plic;
- ff_gateway_queue[i].enq(0);
- endrule
- `endif
- end
- */
- rule rl_connect_i2c0_to_plic;
- `ifdef I2C0
- if(i2c0.isint()==1'b1) begin
- ff_gateway_queue[8].enq(1);
- plic.ifc_external_irq[8].irq_frm_gateway(True);
- end
- `else
- ff_gateway_queue[8].enq(0);
- `endif
- endrule
-
- rule rl_connect_i2c1_to_plic;
- `ifdef I2C1
- if(i2c1.isint()==1'b1) begin
- ff_gateway_queue[9].enq(1);
- plic.ifc_external_irq[9].irq_frm_gateway(True);
- end
- `else
- ff_gateway_queue[9].enq(0);
- `endif
- endrule
-
- rule rl_connect_i2c0_timerint_to_plic;
- `ifdef I2C0
- if(i2c0.timerint()==1'b1) begin
- ff_gateway_queue[10].enq(1);
- plic.ifc_external_irq[10].irq_frm_gateway(True);
- end
- `else
- ff_gateway_queue[10].enq(0);
- `endif
- endrule
-
- rule rl_connect_i2c1_timerint_to_plic;
- `ifdef I2C1
- if(i2c1.timerint()==1'b1) begin
- ff_gateway_queue[11].enq(1);
- plic.ifc_external_irq[11].irq_frm_gateway(True);
- end
- `else
- ff_gateway_queue[11].enq(0);
- `endif
- endrule
-
- rule rl_connect_i2c0_isber_to_plic;
- `ifdef I2C0
- if(i2c0.isber()==1'b1) begin
- ff_gateway_queue[12].enq(1);
- plic.ifc_external_irq[12].irq_frm_gateway(True);
- end
- `else
- ff_gateway_queue[12].enq(0);
- `endif
- endrule
-
- rule rl_connect_i2c1_isber_to_plic;
- `ifdef I2C1
- if(i2c1.isber()==1'b1) begin
- ff_gateway_queue[13].enq(1);
- plic.ifc_external_irq[13].irq_frm_gateway(True);
- end
- `else
- ff_gateway_queue[13].enq(0);
- `endif
- endrule
-
- for(Integer i = 14; i < 20; i=i+1) begin
- rule rl_connect_qspi0_to_plic;
- `ifdef QSPI0
- if(qspi0.interrupts()[i-14]==1'b1) begin
- ff_gateway_queue[i].enq(1);
- plic.ifc_external_irq[i].irq_frm_gateway(True);
- end
- `else
- ff_gateway_queue[i].enq(0);
- `endif
- endrule
- end
-
- for(Integer i = 20; i<26; i=i+1) begin
- rule rl_connect_qspi1_to_plic;
- `ifdef QSPI1
- if(qspi1.interrupts()[i-20]==1'b1) begin
- ff_gateway_queue[i].enq(1);
- plic.ifc_external_irq[i].irq_frm_gateway(True);
- end
- `else
- ff_gateway_queue[i].enq(0);
- `endif
- endrule
- end
-
- `ifdef UART0
- SyncBitIfc#(Bit#(1)) uart0_interrupt <-mkSyncBitToCC(uart_clock,uart_reset);
- rule synchronize_the_uart0_interrupt;
- uart0_interrupt.send(uart0.irq);
- endrule
- `endif
- rule rl_connect_uart_to_plic;
- `ifdef UART0
- if(uart0_interrupt.read==1'b1) begin
- ff_gateway_queue[27].enq(1);
- plic.ifc_external_irq[27].irq_frm_gateway(True);
- end
-
- `else
- ff_gateway_queue[27].enq(0);
- `endif
- endrule
-
- for(Integer i = 28; i<`INTERRUPT_PINS; i=i+1) begin
- rule rl_raise_interrupts;
- if((i-28)<`IONum) begin //Peripheral interrupts
- if(gpio.to_plic[i-28]==1'b1) begin
- plic.ifc_external_irq[i].irq_frm_gateway(True);
- ff_gateway_queue[i].enq(1);
- end
- end
- endrule
- end
-
- rule rl_completion_msg_from_plic;
- let id <- plic.intrpt_completion;
- interrupt_id <= id;
- `ifdef verbose $display("Dequeing the FIFO -- PLIC Interrupt Serviced id: %d",id); `endif
- endrule
-
- for(Integer i=0; i <`INTERRUPT_PINS; i=i+1) begin
- rule deq_gateway_queue;
- if(interrupt_id==fromInteger(i)) begin
- ff_gateway_queue[i].deq;
- `ifdef $display($time,"Dequeing the Interrupt request for ID: %d",i); `endif
- end
- endrule
- end
-
-
- `endif
- /*======================================================= */
-
- /* ===== interface definition =======*/
- interface axi_slave=bridge.axi_slave;
- `ifdef PLIC method intrpt_note = plic.intrpt_note; `endif
- `ifdef CLINT
- method msip_int=clint.msip_int;
- method mtip_int=clint.mtip_int;
- method mtime=clint.mtime;
- `endif
- `ifdef I2C0
- method i2c0_isint=i2c0.isint;
- `endif
- `ifdef I2C1
- method i2c1_isint=i2c1.isint;
- `endif
- `ifdef QSPI0 method qspi0_isint=qspi0.interrupts[5]; `endif
- `ifdef QSPI1 method qspi1_isint=qspi1.interrupts[5]; `endif
- `ifdef UART0 method uart0_intr=uart0.irq; `endif
- interface SP_ios slow_ios;
- `ifdef UART0
- interface uart0_coe=uart0.coe_rs232;
- `endif
- `ifdef UART1
- interface uart1_coe=uart1.coe_rs232;
- `endif
- `ifdef PLIC
- method Action gpio_in (Vector#(`IONum,Bit#(1)) inp)=gpio.gpio_in(inp);
- method Vector#(`IONum,Bit#(1)) gpio_out=gpio.gpio_out;
- method Vector#(`IONum,Bit#(1)) gpio_out_en=gpio.gpio_out_en;
- `endif
- `ifdef I2C0
- interface i2c0_out=i2c0.out;
- `endif
- `ifdef I2C1
- interface i2c1_out=i2c1.out;
- `endif
- `ifdef QSPI0
- interface qspi0_out = qspi0.out;
- `endif
- `ifdef QSPI1
- interface qspi1_out = qspi1.out;
- `endif
- `ifdef AXIEXP
- interface axiexp1_out=axiexp1.slave_out;
- interface axiexp1_in=axiexp1.slave_in;
- `endif
- `ifdef PWM_AXI4Lite
- interface pwm_o = pwm_bus.pwm_io;
- `endif
- endinterface
- // NEEL EDIT
- interface iocell_side=pinmux.iocell_side;
- interface pad_configa= gpioa.pad_config;
- // NEEL EDIT OVER
- /*===================================*/
- endmodule
-endpackage
--- /dev/null
+package slow_peripherals;
+ /*===== Project imports =====*/
+ import defined_types::*;
+ import AXI4_Lite_Fabric::*;
+ import AXI4_Lite_Types::*;
+ import AXI4_Fabric::*;
+ import AXI4_Types::*;
+ import Semi_FIFOF::*;
+ import AXI4Lite_AXI4_Bridge::*;
+ `include "instance_defines.bsv"
+ /*===========================*/
+ /*=== package imports ===*/
+ import Clocks::*;
+ import GetPut::*;
+ import ClientServer::*;
+ import Connectable::*;
+ import Vector::*;
+ import FIFO::*;
+ /*=======================*/
+ /*===== Import the slow peripherals ====*/
+ `ifdef UART0
+ import Uart16550 :: *;
+ `endif
+ `ifdef UART1
+ import Uart_bs::*;
+ import RS232_modified::*;
+ `endif
+ `ifdef CLINT
+ import clint::*;
+ `endif
+ `ifdef PLIC
+ import plic ::*;
+ `endif
+ `ifdef I2C0
+ import I2C_top :: *;
+ `endif
+ `ifdef QSPI0
+ import qspi :: *;
+ `endif
+ `ifdef AXIEXP
+ import axiexpansion ::*;
+ `endif
+ `ifdef PWM_AXI4Lite
+ import pwm::*;
+ `endif
+ // NEEL EDIT
+ import pinmux::*;
+ import mux::*;
+ import gpio::*;
+ /*=====================================*/
+
+ /*===== interface declaration =====*/
+ interface SP_ios;
+ `ifdef UART0
+ interface RS232_PHY_Ifc uart0_coe;
+ `endif
+ `ifdef UART1
+ interface RS232 uart1_coe;
+ `endif
+ `ifdef PLIC
+ (*always_ready,always_enabled*)
+ method Action gpio_in (Vector#(`IONum,Bit#(1)) inp);
+ (*always_ready,always_enabled*)
+ method Vector#(`IONum,Bit#(1)) gpio_out;
+ (*always_ready,always_enabled*)
+ method Vector#(`IONum,Bit#(1)) gpio_out_en;
+ `endif
+ `ifdef I2C0
+ interface I2C_out i2c0_out;
+ `endif
+ `ifdef I2C1
+ interface I2C_out i2c1_out;
+ `endif
+ `ifdef QSPI0
+ interface QSPI_out qspi0_out;
+ `endif
+ `ifdef QSPI1
+ interface QSPI_out qspi1_out;
+ `endif
+ `ifdef AXIEXP
+ interface Get#(Bit#(67)) axiexp1_out;
+ interface Put#(Bit#(67)) axiexp1_in;
+ `endif
+ `ifdef PWM_AXI4Lite
+ interface PWMIO pwm_o;
+ `endif
+ endinterface
+ interface Ifc_slow_peripherals;
+ interface AXI4_Slave_IFC#(`PADDR,`Reg_width,`USERSPACE) axi_slave;
+ interface SP_ios slow_ios;
+ `ifdef CLINT
+ method Bit#(1) msip_int;
+ method Bit#(1) mtip_int;
+ method Bit#(`Reg_width) mtime;
+ `endif
+ `ifdef PLIC method ActionValue#(Tuple2#(Bool,Bool)) intrpt_note; `endif
+ `ifdef I2C0 method Bit#(1) i2c0_isint; `endif
+ `ifdef I2C1 method Bit#(1) i2c1_isint; `endif
+ `ifdef QSPI0 method Bit#(1) qspi0_isint; `endif
+ `ifdef QSPI1 method Bit#(1) qspi1_isint; `endif
+ `ifdef UART0 method Bit#(1) uart0_intr; `endif
+ // NEEL EDIT
+ interface IOCellSide iocell_side; // mandatory interface
+ interface GPIO_config#(3) pad_configa; // depends on the number of banks
+ // NEEL EDIT OVER
+ endinterface
+ /*================================*/
+
+ function Tuple2#(Bool, Bit#(TLog#(Num_Slow_Slaves))) fn_address_mapping (Bit#(`PADDR) addr);
+ `ifdef UART0
+ if(addr>=`UART0Base && addr<=`UART0End)
+ return tuple2(True,fromInteger(valueOf(Uart0_slave_num)));
+ else
+ `endif
+ `ifdef UART1
+ if(addr>=`UART1Base && addr<=`UART1End)
+ return tuple2(True,fromInteger(valueOf(Uart1_slave_num)));
+ else
+ `endif
+ `ifdef CLINT
+ if(addr>=`ClintBase && addr<=`ClintEnd)
+ return tuple2(True,fromInteger(valueOf(CLINT_slave_num)));
+ else
+ `endif
+ `ifdef PLIC
+ if(addr>=`PLICBase && addr<=`PLICEnd)
+ return tuple2(True,fromInteger(valueOf(Plic_slave_num)));
+ else if(addr>=`GPIOBase && addr<=`GPIOEnd)
+ return tuple2(True,fromInteger(valueOf(GPIO_slave_num)));
+ else
+ `endif
+ `ifdef I2C0
+ if(addr>=`I2C0Base && addr<=`I2C0End)
+ return tuple2(True,fromInteger(valueOf(I2c0_slave_num)));
+ else
+ `endif
+ `ifdef I2C1
+ if(addr>=`I2C1Base && addr<=`I2C1End)
+ return tuple2(True,fromInteger(valueOf(I2c1_slave_num)));
+ else
+ `endif
+ `ifdef QSPI0
+ if(addr>=`QSPI0CfgBase && addr<=`QSPI0CfgEnd)
+ return tuple2(True,fromInteger(valueOf(Qspi0_slave_num)));
+ else if(addr>=`QSPI0MemBase && addr<=`QSPI0MemEnd)
+ return tuple2(True,fromInteger(valueOf(Qspi0_slave_num)));
+ else
+ `endif
+ `ifdef QSPI1
+ if(addr>=`QSPI1CfgBase && addr<=`QSPI1CfgEnd)
+ return tuple2(True,fromInteger(valueOf(Qspi1_slave_num)));
+ else if(addr>=`QSPI1MemBase && addr<=`QSPI1MemEnd)
+ return tuple2(True,fromInteger(valueOf(Qspi1_slave_num)));
+ else
+ `endif
+ `ifdef AXIEXP
+ if(addr>=`AxiExp1Base && addr<=`AxiExp1End)
+ return tuple2(True,fromInteger(valueOf(AxiExp1_slave_num)));
+ else
+ `endif
+ `ifdef PWM_AXI4Lite
+ if(addr>=`PWMBase && addr<=`PWMEnd)
+ return tuple2(True,fromInteger(valueOf(Pwm_slave_num)));
+ else
+ `endif
+
+ // NEEL EDIT
+ // give slave number and adress map to whatever peripherals you instantiate on the AXI4_Lite
+ // slave.
+ // NEEL EDIT OVER
+ return tuple2(False,?);
+ endfunction
+
+ (*synthesize*)
+ module mkslow_peripherals#(Clock fast_clock, Reset fast_reset, Clock uart_clock, Reset uart_reset
+ `ifdef PWM_AXI4Lite ,Clock ext_pwm_clock `endif )(Ifc_slow_peripherals);
+ Clock sp_clock <-exposeCurrentClock; // slow peripheral clock
+ Reset sp_reset <-exposeCurrentReset; // slow peripheral reset
+
+ /*======= Module declarations for each peripheral =======*/
+ `ifdef UART0
+ Uart16550_AXI4_Lite_Ifc uart0 <- mkUart16550(clocked_by uart_clock, reset_by uart_reset, sp_clock, sp_reset);
+ `endif
+ `ifdef UART1
+ Ifc_Uart_bs uart1 <- mkUart_bs(clocked_by uart_clock, reset_by uart_reset,sp_clock, sp_reset);
+ `endif
+ `ifdef CLINT
+ Ifc_clint clint <- mkclint();
+ `endif
+ `ifdef PLIC
+ Ifc_PLIC_AXI plic <- mkplicperipheral();
+ Wire#(Bit#(TLog#(`INTERRUPT_PINS))) interrupt_id <- mkWire();
+ Vector#(`INTERRUPT_PINS, FIFO#(bit)) ff_gateway_queue <- replicateM(mkFIFO);
+ GPIO gpio <- mkgpio;
+ `endif
+ `ifdef I2C0
+ I2C_IFC i2c0 <- mkI2CController();
+ `endif
+ `ifdef I2C1
+ I2C_IFC i2c1 <- mkI2CController();
+ `endif
+ `ifdef QSPI0
+ Ifc_qspi qspi0 <- mkqspi();
+ `endif
+ `ifdef QSPI1
+ Ifc_qspi qspi1 <- mkqspi();
+ `endif
+ `ifdef AXIEXP
+ Ifc_AxiExpansion axiexp1 <- mkAxiExpansion();
+ `endif
+ `ifdef PWM_AXI4Lite
+ Ifc_PWM_bus pwm_bus <- mkPWM_bus(ext_pwm_clock);
+ `endif
+ // NEEL EDIT
+ Ifc_pinmux pinmux <- mkpinmux; // mandatory
+ MUX#(3) mymux <- mkmux(); // mandatory. number depends on the number of instances required.
+ GPIO#(3) mygpioa <- mkgpio(); // optional. depends the number of IO pins declared before.
+ // NEEL EDIT OVER
+ /*=======================================================*/
+
+ AXI4_Lite_Fabric_IFC #(1, Num_Slow_Slaves, `PADDR, `Reg_width,`USERSPACE) slow_fabric <-
+ mkAXI4_Lite_Fabric(fn_address_mapping);
+ Ifc_AXI4Lite_AXI4_Bridge bridge <-mkAXI4Lite_AXI4_Bridge(fast_clock,fast_reset);
+
+ mkConnection (bridge.axi4_lite_master, slow_fabric.v_from_masters [0]);
+ /*======= Slave connections to AXI4Lite fabric =========*/
+ `ifdef UART0
+ mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(Uart0_slave_num))],
+ uart0.slave_axi_uart);
+ `endif
+ `ifdef UART1
+ mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(Uart1_slave_num))],
+ uart1.slave_axi_uart);
+ `endif
+ `ifdef CLINT
+ mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(CLINT_slave_num))],
+ clint.axi4_slave);
+ `endif
+ `ifdef PLIC
+ mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(Plic_slave_num))],
+ plic.axi4_slave_plic); //
+ mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(GPIO_slave_num))],
+ gpio.axi_slave); //
+ `endif
+ `ifdef I2C0
+ mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(I2c0_slave_num))],
+ i2c0.slave_i2c_axi);
+ `endif
+ `ifdef I2C1
+ mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(I2c1_slave_num))],
+ i2c1.slave_i2c_axi); //
+ `endif
+ `ifdef QSPI0
+ mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(Qspi0_slave_num))],
+ qspi0.slave);
+ `endif
+ `ifdef QSPI1
+ mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(Qspi1_slave_num))],
+ qspi1.slave);
+ `endif
+ `ifdef AXIEXP
+ mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(AxiExp1_slave_num))],
+ axiexp1.axi_slave); //
+ `endif
+ `ifdef PWM_AXI4Lite
+ mkConnection (slow_fabric.v_to_slaves [fromInteger(valueOf(Pwm_slave_num))],
+ pwm_bus.axi4_slave);
+ `endif
+
+ // NEEL EDIT
+ mkConnection (slow_fabric.v_from_masters[fromInteger(valueOf(Muxa_slave_num))], mymux.axi_slave);
+ mkConnection (slow_fabric.v_from_masters[fromInteger(valueOf(Gpioa_slave_num))], gpioa.axi_slave);
+ rule connect_select_lines_pinmux;// mandatory
+ pinmux.cell0_mux(mymux.mux_config[0]);
+ pinmux.cell1_mux(mymux.mux_config[1]);
+ pinmux.cell2_mux(mymux.mux_config[2]);
+ endrule
+ rule connect_uart1tx;
+ pinmux.peripheral_side.uart_tx(uart1.coe_rs232.rs232.sout);
+ endrule
+ rule connect_uart1rx;
+ uart1.coe_rs232.rs232.sin(pinmux.peripheral_side.uart_rx);
+ endrule
+ rule connect_gpioa;
+ pinmux.peripheral_side.gpioa_a0_out(gpio.func.gpio_out[0]);
+ pinmux.peripheral_side.gpioa_a0_outen(gpio.func.gpio_out_en[0]);
+ Vector#(3,Bit#(1)) temp;
+ temp[0]=pinmux.peripheral_side.gpioa_a0_in;
+ temp[1]=pinmux.peripheral_side.gpioa_a1_in;
+ temp[2]=pinmux.peripheral_side.gpioa_a2_in;
+ gpio.pad_config.gpio_in(temp);
+ endrule
+ // NEEL EDIT OVER
+ /*=======================================================*/
+ /*=================== PLIC Connections ==================== */
+ `ifdef PLIC
+ /*TODO DMA interrupt need to be connected to the plic
+ for(Integer i=1; i<8; i=i+1) begin
+ `ifdef DMA
+ rule rl_connect_dma_interrupts_to_plic;
+ if(dma.interrupt_to_processor[i-1]==1'b1) begin
+ ff_gateway_queue[i].enq(1);
+ plic.ifc_external_irq[i].irq_frm_gateway(True);
+ end
+ endrule
+ `else
+ rule rl_connect_dma_interrupts_to_plic;
+ ff_gateway_queue[i].enq(0);
+ endrule
+ `endif
+ end
+ */
+ rule rl_connect_i2c0_to_plic;
+ `ifdef I2C0
+ if(i2c0.isint()==1'b1) begin
+ ff_gateway_queue[8].enq(1);
+ plic.ifc_external_irq[8].irq_frm_gateway(True);
+ end
+ `else
+ ff_gateway_queue[8].enq(0);
+ `endif
+ endrule
+
+ rule rl_connect_i2c1_to_plic;
+ `ifdef I2C1
+ if(i2c1.isint()==1'b1) begin
+ ff_gateway_queue[9].enq(1);
+ plic.ifc_external_irq[9].irq_frm_gateway(True);
+ end
+ `else
+ ff_gateway_queue[9].enq(0);
+ `endif
+ endrule
+
+ rule rl_connect_i2c0_timerint_to_plic;
+ `ifdef I2C0
+ if(i2c0.timerint()==1'b1) begin
+ ff_gateway_queue[10].enq(1);
+ plic.ifc_external_irq[10].irq_frm_gateway(True);
+ end
+ `else
+ ff_gateway_queue[10].enq(0);
+ `endif
+ endrule
+
+ rule rl_connect_i2c1_timerint_to_plic;
+ `ifdef I2C1
+ if(i2c1.timerint()==1'b1) begin
+ ff_gateway_queue[11].enq(1);
+ plic.ifc_external_irq[11].irq_frm_gateway(True);
+ end
+ `else
+ ff_gateway_queue[11].enq(0);
+ `endif
+ endrule
+
+ rule rl_connect_i2c0_isber_to_plic;
+ `ifdef I2C0
+ if(i2c0.isber()==1'b1) begin
+ ff_gateway_queue[12].enq(1);
+ plic.ifc_external_irq[12].irq_frm_gateway(True);
+ end
+ `else
+ ff_gateway_queue[12].enq(0);
+ `endif
+ endrule
+
+ rule rl_connect_i2c1_isber_to_plic;
+ `ifdef I2C1
+ if(i2c1.isber()==1'b1) begin
+ ff_gateway_queue[13].enq(1);
+ plic.ifc_external_irq[13].irq_frm_gateway(True);
+ end
+ `else
+ ff_gateway_queue[13].enq(0);
+ `endif
+ endrule
+
+ for(Integer i = 14; i < 20; i=i+1) begin
+ rule rl_connect_qspi0_to_plic;
+ `ifdef QSPI0
+ if(qspi0.interrupts()[i-14]==1'b1) begin
+ ff_gateway_queue[i].enq(1);
+ plic.ifc_external_irq[i].irq_frm_gateway(True);
+ end
+ `else
+ ff_gateway_queue[i].enq(0);
+ `endif
+ endrule
+ end
+
+ for(Integer i = 20; i<26; i=i+1) begin
+ rule rl_connect_qspi1_to_plic;
+ `ifdef QSPI1
+ if(qspi1.interrupts()[i-20]==1'b1) begin
+ ff_gateway_queue[i].enq(1);
+ plic.ifc_external_irq[i].irq_frm_gateway(True);
+ end
+ `else
+ ff_gateway_queue[i].enq(0);
+ `endif
+ endrule
+ end
+
+ `ifdef UART0
+ SyncBitIfc#(Bit#(1)) uart0_interrupt <-mkSyncBitToCC(uart_clock,uart_reset);
+ rule synchronize_the_uart0_interrupt;
+ uart0_interrupt.send(uart0.irq);
+ endrule
+ `endif
+ rule rl_connect_uart_to_plic;
+ `ifdef UART0
+ if(uart0_interrupt.read==1'b1) begin
+ ff_gateway_queue[27].enq(1);
+ plic.ifc_external_irq[27].irq_frm_gateway(True);
+ end
+
+ `else
+ ff_gateway_queue[27].enq(0);
+ `endif
+ endrule
+
+ for(Integer i = 28; i<`INTERRUPT_PINS; i=i+1) begin
+ rule rl_raise_interrupts;
+ if((i-28)<`IONum) begin //Peripheral interrupts
+ if(gpio.to_plic[i-28]==1'b1) begin
+ plic.ifc_external_irq[i].irq_frm_gateway(True);
+ ff_gateway_queue[i].enq(1);
+ end
+ end
+ endrule
+ end
+
+ rule rl_completion_msg_from_plic;
+ let id <- plic.intrpt_completion;
+ interrupt_id <= id;
+ `ifdef verbose $display("Dequeing the FIFO -- PLIC Interrupt Serviced id: %d",id); `endif
+ endrule
+
+ for(Integer i=0; i <`INTERRUPT_PINS; i=i+1) begin
+ rule deq_gateway_queue;
+ if(interrupt_id==fromInteger(i)) begin
+ ff_gateway_queue[i].deq;
+ `ifdef $display($time,"Dequeing the Interrupt request for ID: %d",i); `endif
+ end
+ endrule
+ end
+
+
+ `endif
+ /*======================================================= */
+
+ /* ===== interface definition =======*/
+ interface axi_slave=bridge.axi_slave;
+ `ifdef PLIC method intrpt_note = plic.intrpt_note; `endif
+ `ifdef CLINT
+ method msip_int=clint.msip_int;
+ method mtip_int=clint.mtip_int;
+ method mtime=clint.mtime;
+ `endif
+ `ifdef I2C0
+ method i2c0_isint=i2c0.isint;
+ `endif
+ `ifdef I2C1
+ method i2c1_isint=i2c1.isint;
+ `endif
+ `ifdef QSPI0 method qspi0_isint=qspi0.interrupts[5]; `endif
+ `ifdef QSPI1 method qspi1_isint=qspi1.interrupts[5]; `endif
+ `ifdef UART0 method uart0_intr=uart0.irq; `endif
+ interface SP_ios slow_ios;
+ `ifdef UART0
+ interface uart0_coe=uart0.coe_rs232;
+ `endif
+ `ifdef UART1
+ interface uart1_coe=uart1.coe_rs232;
+ `endif
+ `ifdef PLIC
+ method Action gpio_in (Vector#(`IONum,Bit#(1)) inp)=gpio.gpio_in(inp);
+ method Vector#(`IONum,Bit#(1)) gpio_out=gpio.gpio_out;
+ method Vector#(`IONum,Bit#(1)) gpio_out_en=gpio.gpio_out_en;
+ `endif
+ `ifdef I2C0
+ interface i2c0_out=i2c0.out;
+ `endif
+ `ifdef I2C1
+ interface i2c1_out=i2c1.out;
+ `endif
+ `ifdef QSPI0
+ interface qspi0_out = qspi0.out;
+ `endif
+ `ifdef QSPI1
+ interface qspi1_out = qspi1.out;
+ `endif
+ `ifdef AXIEXP
+ interface axiexp1_out=axiexp1.slave_out;
+ interface axiexp1_in=axiexp1.slave_in;
+ `endif
+ `ifdef PWM_AXI4Lite
+ interface pwm_o = pwm_bus.pwm_io;
+ `endif
+ endinterface
+ // NEEL EDIT
+ interface iocell_side=pinmux.iocell_side;
+ interface pad_configa= gpioa.pad_config;
+ // NEEL EDIT OVER
+ /*===================================*/
+ endmodule
+endpackage