add libraries
[shakti-core.git] / src / testbench / FlexBus_Slave_to_AXI4_Master_Fabric_Types.bsv
diff --git a/src/testbench/FlexBus_Slave_to_AXI4_Master_Fabric_Types.bsv b/src/testbench/FlexBus_Slave_to_AXI4_Master_Fabric_Types.bsv
new file mode 100644 (file)
index 0000000..e28b5f7
--- /dev/null
@@ -0,0 +1,399 @@
+
+package FlexBus_Slave_to_AXI4_Master_Fabric_Types;
+
+// ================================================================
+// Exports
+
+export
+
+FlexBus_Slave_to_AXI4_Master_Fabric_IFC (..),
+
+// Transactors from RTL-level interfacecs to FIFO-like interfaces.
+mkFlexBus_Slave_to_AXI4_Master_Fabric;
+
+// ================================================================
+// BSV library imports
+
+import ConfigReg ::*;
+import FIFOF       :: *;
+import SpecialFIFOs::*;
+import Connectable :: *;
+import TriState ::*;
+`include "defined_parameters.bsv"
+
+// ----------------
+// BSV additional libs
+
+import Semi_FIFOF :: *;
+
+import FlexBus_Types :: *; 
+import AXI4_Types   :: *;
+
+function Bit#(wd_addr) address_increment(Bit#(8) arlen, Bit#(3) arsize, Bit#(2) arburst, Bit#(wd_addr) address)
+provisos(
+                Add#(a__, 4, wd_addr),
+                Add#(b__, 3, wd_addr),
+                Add#(c__, 2, wd_addr));
+                // bit_width_size= (2^arsize)*8
+                // arburst = 0(FIXED), 1(INCR) and 2(WRAP)
+                       if(arburst==0) // FIXED
+                             return address;
+                       else if(arburst==1)begin // INCR
+                             return address+ (('b1)<<arsize);
+                       end
+                       else begin // WRAP
+                            let new_addr=address;
+                            case (arlen)
+                                1: new_addr[arsize]=~address[arsize];
+                                3: begin
+                                     if(arsize==0)
+                                           new_addr[1:0]=new_addr[1:0]+1;
+                                     else if(arsize==1)
+                                           new_addr[2:1]=new_addr[2:1]+1;
+                                     else if(arsize==2)
+                                           new_addr[3:2]=new_addr[3:2]+1;
+                                     else if(arsize==3)
+                                           new_addr[4:3]=new_addr[4:3]+1;
+                                   end
+                                7: begin
+                                      if(arsize==0)
+                                           new_addr[2:0]=new_addr[2:0]+1;
+                                      else if(arsize==1)
+                                           new_addr[3:1]=new_addr[3:1]+1;
+                                      else if(arsize==2)
+                                           new_addr[4:2]=new_addr[4:2]+1;
+                                      else if(arsize==3)
+                                           new_addr[5:3]=new_addr[5:3]+1;
+                                   end
+                                15:begin //Bit#(4) x = address[arsize+3:arsize]+1;new_addr[arsize+3:arsize]=x;end
+                                      if(arsize==0)
+                                            new_addr[3:0]=new_addr[3:0]+1;
+                                      else if(arsize==1)
+                                            new_addr[4:1]=new_addr[4:1]+1;
+                                      else if(arsize==2)
+                                            new_addr[5:2]=new_addr[5:2]+1;
+                                      else if(arsize==3)
+                                            new_addr[6:3]=new_addr[6:3]+1;
+                                 end
+                           endcase
+                           return new_addr;
+                    end
+               endfunction
+// ================================================================
+/*
+module mkVerfn_Top (Empty);
+
+       FlexBus_Slave_to_AXI4_Master_Fabric_IFC#(32,32,4) verfn_ifc <- mkFlexBus_Slave_to_AXI4_Master_Fabric;
+
+        AXI4_Slave_to_FlexBus_Master_Xactor_IFC#(32, 32, 4)
+                                                  flexbus_xactor_ifc <- mkAXI4_Slave_to_FlexBus_Master_Xactor;
+
+        mkConnection(flexbus_xactor_ifc.flexbus_side,verfn_ifc.flexbus_side);
+
+endmodule 
+*/
+// ================================================================
+// Master Fabric interface
+
+interface FlexBus_Slave_to_AXI4_Master_Fabric_IFC #(numeric type wd_addr,
+                                       numeric type wd_data,
+                                       numeric type wd_user);
+   method Action reset;
+
+   // FlexBus side
+   interface FlexBus_Slave_IFC flexbus_side;
+
+   // AXI side
+   interface AXI4_Master_IFC #(wd_addr, wd_data, wd_user) axi_side;
+
+endinterface: FlexBus_Slave_to_AXI4_Master_Fabric_IFC
+
+// ----------------------------------------------------------------
+// Master transactor
+
+module mkFlexBus_Slave_to_AXI4_Master_Fabric (FlexBus_Slave_to_AXI4_Master_Fabric_IFC #(wd_addr, wd_data, wd_user))
+provisos(
+                         Add#(a__, 4, wd_addr),
+                         Add#(b__, 3, wd_addr),
+                         Add#(c__, 2, wd_addr),
+             Bits#(Bit#(32), wd_addr),
+             Bits#(Bit#(64), wd_data));
+
+  ConfigReg#(FlexBus_States) flexbus_state_verfn <- mkConfigReg(FlexBus_S1_ADDR);
+
+  Reg#(Bit#(32)) r_AD  <- mkReg(32'h00000000);
+  Reg#(Bit#(1)) r_ALE          <- mkReg(1'b0);
+  Reg#(Bit#(1)) r_R_Wn                 <- mkReg(1'b0);
+  Reg#(Bit#(2)) r_TSIZ                 <- mkReg(2'b00);
+  Reg#(Bit#(6)) r_FBCSn        <- mkReg(6'h00);
+  Reg#(Bit#(4)) r_BE_BWEn      <- mkReg(4'h0);
+  Reg#(Bit#(1)) r_TBSTn        <- mkReg(1'b0);
+  Reg#(Bit#(1)) r_OEn          <- mkReg(1'b0);
+
+  Reg#(Bool)    r1_OEn      <- mkReg(True);
+
+  Reg#(Bit#(32)) r_din         <- mkReg(0);
+  Reg#(Bit#(1)) r_TAn          <- mkReg(1'b0);
+
+  Reg#(Bit#(6)) r_WS_val       <- mkReg(6'h02);
+  Reg#(Bit#(6)) r_WS           <- mkReg(6'h00);
+
+   Bool unguarded = True;
+   Bool guarded   = False;
+
+  Reg#(Maybe#(AXI4_Wr_Addr #(wd_addr, wd_user))) f_wr_addr[3] <-mkCReg(3,tagged Invalid);
+  Reg#(Maybe#(AXI4_Wr_Data #(wd_data)))          f_wr_data[3] <-mkCReg(3,tagged Invalid);
+  Reg#(Maybe#(AXI4_Wr_Resp #(wd_user)))          f_wr_resp[3] <-mkCReg(3,tagged Invalid);
+
+
+   Reg#(Maybe#(AXI4_Rd_Addr #(wd_addr, wd_user)))  f_rd_addr[3] <- mkCReg(3,tagged Invalid);
+   Reg#(Maybe#(AXI4_Rd_Data #(wd_data, wd_user))) f_rd_data[3] <- mkCReg(3, tagged Invalid);
+   Reg#(Maybe#(AXI4_Rd_Addr #(wd_addr, wd_user)))  rd_req_reg[2] <- mkCReg(2,tagged Invalid);
+        Reg#(Bit#(8)) rg_read_burst_cycle <-mkReg(0);
+
+   //  TriState#(Bit#(32)) tri_AD_in <- mkTriState(!r1_OEn,r_din);
+
+        rule rl_OEn;
+            if (r_OEn == 1'b0)
+                r1_OEn <= False;
+            else
+                r1_OEn <= True;
+        endrule
+
+     //   rule rl_read_AD_bus;
+       //     r_AD <= tri_AD_in._read;
+     //   endrule
+
+               rule generate_read_request(rd_req_reg[1] matches tagged Valid .ar &&& f_rd_addr[0] matches tagged Invalid);
+                       `ifdef verbose_debug_ver $display("generate_read_request FIRED");`endif
+                       `ifdef verbose $display($time,"\tAXI4MasterRead: Generating Read Request for Address: %h BurstSize: %d BurstLength: %d BurstMode: :%d",ar.araddr,ar.arsize,ar.arlen,ar.arburst); `endif
+                       f_rd_addr[0]<=tagged Valid ar;
+                       let info=ar;
+                       if(ar.arlen==rg_read_burst_cycle) begin// end of burst
+                               rd_req_reg[1]<= tagged Invalid;
+                               rg_read_burst_cycle<=0;
+                       end
+                       else begin
+                               info.araddr=address_increment(ar.arlen,ar.arsize,ar.arburst,ar.araddr);
+                               rg_read_burst_cycle<=rg_read_burst_cycle+1;
+                               rd_req_reg[1]<=tagged Valid info;
+                       end
+               endrule
+
+   Reg#(Maybe#(AXI4_Wr_Addr #(wd_addr, wd_user)))  wr_req_reg[2] <- mkCReg(2,tagged Invalid);
+   Reg#(Maybe#(AXI4_Wr_Data #(wd_data)))  wr_data_reg[2] <- mkCReg(2,tagged Invalid);
+        Reg#(Bit#(8)) rg_write_burst_cycle <-mkReg(0);
+        rule generate_write_request(wr_req_reg[1] matches tagged Valid .ar &&& wr_data_reg[1] matches tagged Valid .wd &&& f_wr_addr[0] matches tagged Invalid &&& f_wr_data[0] matches tagged Invalid);
+                       `ifdef verbose_debug_ver $display("generate_write_request FIRED"); `endif
+                       `ifdef verbose $display($time,"\tAXI4MasterWrite: Generating Write Request for Address: %h Data: %h BurstSize: %d BurstLength: %d BurstMode: :%d",ar.awaddr,wd.wdata,ar.awsize,ar.awlen,ar.awburst); `endif
+                       f_wr_addr[0]<=tagged Valid ar;
+                       f_wr_data[0]<=tagged Valid wd;
+                       let info=ar;
+                       if(ar.awlen==rg_write_burst_cycle) begin// end of burst
+                               wr_req_reg[1]<= tagged Invalid;
+                               wr_data_reg[1]<= tagged Invalid;
+                               rg_write_burst_cycle<=0;
+                       end
+                       else begin
+                               info.awaddr=address_increment(ar.awlen,ar.awsize,ar.awburst,ar.awaddr);
+                               rg_write_burst_cycle<=rg_write_burst_cycle+1;
+                               wr_req_reg[1]<=tagged Valid info;
+                       end
+               endrule
+
+               rule rl_generate_addr (r_ALE== 1 && flexbus_state_verfn == FlexBus_S1_ADDR );
+                       `ifdef verbose_debug_ver $display("STATE S1 ADDR VERFN fired "); `endif
+                       r_WS <= r_WS_val;
+                       if (r_R_Wn == 1'b1) begin
+                               if(rd_req_reg[0] matches tagged Invalid) begin
+                                       rd_req_reg[0]<=tagged Valid (AXI4_Rd_Addr {araddr : pack({r_AD}),
+                                                                         aruser : 0,
+                                                                         arsize : 3'h2,
+                                                                         arlen  : 8'h00,
+                                                                         arburst: 2'b00,
+                                                                         arid : 0
+                                                                       });
+                               end
+                       end
+                       else begin
+                               if(wr_req_reg[0] matches tagged Invalid) begin
+                                       wr_req_reg[0]<=tagged Valid (AXI4_Wr_Addr {awaddr :pack({r_AD}),
+                                                                         awuser : 0,
+                                                                         awsize : 3'h2,
+                                                                         awlen  : 8'h00,
+                                                                         awburst: 2'b00,
+                                                                         awid : 0
+                                                                       });
+                               end
+                       end
+                       flexbus_state_verfn <= FlexBus_S2_WRITE; 
+               endrule
+               rule rl_state_S2_WRITE (flexbus_state_verfn == FlexBus_S2_WRITE); //Write Phase
+                       `ifdef verbose_debug_ver $display("STATE S2 WRITE VERFN FIRED"); `endif
+                       if (r_R_Wn == 1'b0) begin
+                               if(wr_data_reg[0] matches tagged Invalid) begin
+                                       wr_data_reg[0]<=tagged Valid (AXI4_Wr_Data{wdata: pack({32'h00000000,r_AD[7:0],r_AD[15:8],r_AD[23:16],r_AD[31:24]}),
+                                                                        wstrb  : 8'h0F,
+                                                                        wid    : 0,
+                                                                        wlast  : True
+                                                                       });
+                               end
+                       end
+                       if (r_WS == 0) begin
+                               flexbus_state_verfn <= FlexBus_S3_BURST; 
+                               r_WS <= r_WS_val;
+                       end
+                       else
+                               r_WS <= r_WS -1;
+               endrule
+               rule rl_state_S3_BURST (flexbus_state_verfn == FlexBus_S3_BURST); //Burst Phase
+                       `ifdef verbose_debug_ver $display("STATE S3 BURST VERFN FIRED"); `endif
+                       if (r_R_Wn == 1'b1)  begin
+                               if(f_rd_data[1] matches tagged Valid .ar) begin 
+                                       r_din <= ar.rdata[31:0]; 
+                                       `ifdef verbose_debug_ver $display("r_din = %h %h", r_din, ar.rdata); `endif
+                                       f_rd_data[1]<=tagged Invalid;
+                               end
+                       end
+                       flexbus_state_verfn <= FlexBus_S1_ADDR; 
+               endrule
+
+/*
+   // FIFOF side
+        method Action i_wr_addr(AXI4_Wr_Addr#(wd_addr,wd_user) write_address)if(wr_req_reg[0] matches tagged Invalid);
+               wr_req_reg[0]<=tagged Valid write_address;
+       endmethod
+       method Action i_wr_data(AXI4_Wr_Data#(wd_data) write_data);
+               wr_data_reg[0]<=tagged Valid write_data;
+       endmethod
+        method ActionValue#(AXI4_Wr_Resp#(wd_user)) o_wr_resp if(f_wr_resp[1] matches tagged Valid .aresp);
+               f_wr_resp[1]<=tagged Invalid;
+               return aresp;
+        endmethod
+        method Action i_rd_addr(AXI4_Rd_Addr#(wd_addr,wd_user) read_address)if(rd_req_reg[0] matches tagged Invalid);
+               rd_req_reg[0]<=tagged Valid read_address;
+       endmethod
+        method ActionValue#(AXI4_Rd_Data #(wd_data, wd_user)) o_rd_data if(f_rd_data[1] matches tagged Valid .ar);
+               f_rd_data[1]<=tagged Invalid;
+               return ar;
+        endmethod
+*/
+   // ----------------------------------------------------------------
+   // INTERFACE
+
+   method Action reset;
+      f_wr_addr[2]<=tagged Invalid;
+      f_wr_data[2]<=tagged Invalid;
+      f_wr_resp[2]<=tagged Invalid;
+      f_rd_addr[2]<=tagged Invalid;
+      f_rd_data[2]<=tagged Invalid;
+   endmethod
+
+   // AXI side
+   interface axi_side = interface AXI4_Master_IFC;
+                          // Wr Addr channel
+                          method Bool           m_awvalid = isValid(f_wr_addr[1]);
+                          method Bit #(wd_addr) m_awaddr  = fromMaybe(?,f_wr_addr[1]).awaddr;
+                          method Bit #(wd_user) m_awuser  = fromMaybe(?,f_wr_addr[1]).awuser;
+                                method Bit #(3)                         m_awsize        = fromMaybe(?,f_wr_addr[1]).awsize;
+                                method Bit #(8)                         m_awlen   = fromMaybe(?,f_wr_addr[1]).awlen;
+                                method Bit #(2)                         m_awburst = fromMaybe(?,f_wr_addr[1]).awburst;
+                                method Bit #(4)                         m_awid                 =fromMaybe(?,f_wr_addr[1]).awid;
+                          method Action m_awready (Bool awready);
+                             if (isValid(f_wr_addr[1]) && awready) f_wr_addr[1]<=tagged Invalid;
+                          endmethod
+
+                          // Wr Data channel
+                          method Bool                       m_wvalid = isValid(f_wr_data[1]);
+                          method Bit #(wd_data)             m_wdata  = fromMaybe(?,f_wr_data[1]).wdata;
+                          method Bit #(TDiv #(wd_data, 8))  m_wstrb  = fromMaybe(?,f_wr_data[1]).wstrb;
+                          method Bool                       m_wlast =  fromMaybe(?,f_wr_data[1]).wlast;
+                          method Bit#(4)                                                                                m_wid =                fromMaybe(?,f_wr_data[1]).wid;
+                          method Action m_wready (Bool wready);
+                             if (isValid(f_wr_data[1]) && wready) f_wr_data[1]<=tagged Invalid;
+                          endmethod
+
+                          // Wr Response channel
+                          method Action m_bvalid (Bool bvalid, Bit #(2) bresp, Bit #(wd_user) buser, Bit#(4) bid);
+                             if (bvalid && !isValid(f_wr_resp[0]))
+                                                        f_wr_resp[0]<=tagged Valid (AXI4_Wr_Resp {bresp: unpack (bresp), buser: buser, bid: bid});
+                          endmethod
+
+                          method Bool m_bready;
+                             return !isValid(f_wr_resp[0]);
+                          endmethod
+
+                          // Rd Addr channel
+                          method Bool           m_arvalid = isValid(f_rd_addr[1]);
+                          method Bit #(wd_addr) m_araddr  = fromMaybe(?,f_rd_addr[1]).araddr;
+                          method Bit #(wd_user) m_aruser  = fromMaybe(?,f_rd_addr[1]).aruser;
+                                method Bit #(3)                         m_arsize        = fromMaybe(?,f_rd_addr[1]).arsize;
+                                method Bit #(8)                         m_arlen   = fromMaybe(?,f_rd_addr[1]).arlen;
+                                method Bit #(2)                         m_arburst = fromMaybe(?,f_rd_addr[1]).arburst;
+                                method Bit #(4)                         m_arid                 =fromMaybe(?,f_rd_addr[1]).arid;
+                          method Action m_arready (Bool arready);
+                             if (isValid(f_rd_addr[1]) && arready) 
+                                                       f_rd_addr[1]<=tagged Invalid;
+                          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 && !isValid(f_rd_data[0]))
+                                f_rd_data[0]<=tagged Valid (AXI4_Rd_Data {rresp: unpack (rresp),
+                                                                  rdata: rdata,
+                                                                        rlast: rlast,
+                                                                  ruser: ruser,
+                                                                        rid: rid});
+                          endmethod
+
+                          method Bool m_rready;
+                             return !isValid(f_rd_data[0]);
+                          endmethod
+
+                       endinterface;
+
+   interface flexbus_side = interface FlexBus_Slave_IFC;
+    //   interface io_AD_slave = tri_AD_in.io;
+       method Action m_AD             (  Bit #(32)   i_AD);                            // in
+               r_AD <= i_AD;
+       endmethod
+    //interface i_not_AD_s = interface Not_AD_s;
+       method Action m_ALE            (  Bit #(1)         i_ALE);                           // in
+               r_ALE <= i_ALE;
+       endmethod
+
+       method Action m_R_Wn           (  Bit #(1)         i_R_Wn);                          // in
+               r_R_Wn <= i_R_Wn;
+       endmethod
+       method Action m_TSIZ           (  Bit #(2)         i_TSIZ);                          // in
+               r_TSIZ <= i_TSIZ;
+       endmethod
+
+       method Action m_FBCSn          (  Bit #(6)         i_FBCSn);                         // in
+               r_FBCSn <= i_FBCSn;
+       endmethod
+       method Action m_BE_BWEn        (  Bit #(4)         i_BE_BWEn);                       // in
+               r_BE_BWEn <= i_BE_BWEn;
+       endmethod
+       method Action m_TBSTn          (  Bit #(1)         i_TBSTn);                         // in
+               r_TBSTn <= i_TBSTn;
+       endmethod
+       method Action m_OEn            (  Bit #(1)         i_OEn);                           // in
+               r_OEn <= i_OEn;
+       endmethod
+
+       method Bit #(32) m_din = r_din;                         //out
+       method Bit #(1) m_TAn = r_TAn;                                  //out
+    //endinterface;
+                           endinterface;
+
+endmodule: mkFlexBus_Slave_to_AXI4_Master_Fabric
+
+// ================================================================
+
+endpackage