Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added Libraries/AMBA_Fabrics/ and doc/How_to_Contrib #33

Merged
merged 3 commits into from
Nov 21, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
186 changes: 186 additions & 0 deletions Libraries/AMBA_Fabrics/AXI4/AXI4_Addr_Translator.bsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,186 @@
// Copyright (c) 2020 Bluespec, Inc. All Rights Reserved
//
// SPDX-License-Identifier: BSD-3-Clause

package AXI4_Addr_Translator;

// ================================================================
// This package defines transformers for AXI4_M and AXI4_S interfaces
// that perform a simple 'address-translator' (add/subtract a fixed
// constant from address).

// ================================================================
// Bluespec library imports

// none

// ----------------
// BSV additional libs

// none

// ================================================================
// Project imports

import AXI4_Types :: *;

// ================================================================
// M-to-M interface transformer with address translation

function AXI4_M_IFC #(wd_id, wd_addr, wd_data, wd_user)
fv_AXI4_M_Address_Translator (Bool add_not_sub,
Bit #(wd_addr) addr_delta,
AXI4_M_IFC #(wd_id, wd_addr, wd_data, wd_user) ifc);

function Bit #(wd_addr) fv_addr_translate (Bit #(wd_addr) addr);
return (add_not_sub ? addr + addr_delta : addr - addr_delta);
endfunction

return interface AXI4_M_IFC
// Wr Addr channel
method Bool m_awvalid = ifc.m_awvalid; // out
method Bit #(wd_id) m_awid = ifc.m_awid; // out
method Bit #(wd_addr) m_awaddr = fv_addr_translate (ifc.m_awaddr); // out
method Bit #(8) m_awlen = ifc.m_awlen; // out
method AXI4_Size m_awsize = ifc.m_awsize; // out
method Bit #(2) m_awburst = ifc.m_awburst; // out
method Bit #(1) m_awlock = ifc.m_awlock; // out
method Bit #(4) m_awcache = ifc.m_awcache; // out
method Bit #(3) m_awprot = ifc.m_awprot; // out
method Bit #(4) m_awqos = ifc.m_awqos; // out
method Bit #(4) m_awregion = ifc.m_awregion; // out
method Bit #(wd_user) m_awuser = ifc.m_awuser; // out
method Action m_awready (Bool awready) = ifc.m_awready (awready); // in

// Wr Data channel
method Bool m_wvalid = ifc.m_wvalid; // out
method Bit #(wd_data) m_wdata = ifc.m_wdata; // out
method Bit #(TDiv #(wd_data, 8)) m_wstrb = ifc.m_wstrb; // out
method Bool m_wlast = ifc.m_wlast; // out
method Bit #(wd_user) m_wuser = ifc.m_wuser; // out

method Action m_wready (Bool wready) = ifc.m_wready (wready); // in

// Wr Response channel
method Action m_bvalid (Bool bvalid, // in
Bit #(wd_id) bid, // in
Bit #(2) bresp, // in
Bit #(wd_user) buser); // in
ifc.m_bvalid (bvalid, bid, bresp, buser);
endmethod
method Bool m_bready = ifc.m_bready; // out

// Rd Addr channel
method Bool m_arvalid = ifc.m_arvalid; // out
method Bit #(wd_id) m_arid = ifc.m_arid; // out
method Bit #(wd_addr) m_araddr = fv_addr_translate (ifc.m_araddr); // out
method Bit #(8) m_arlen = ifc.m_arlen; // out
method AXI4_Size m_arsize = ifc.m_arsize; // out
method Bit #(2) m_arburst = ifc.m_arburst; // out
method Bit #(1) m_arlock = ifc.m_arlock; // out
method Bit #(4) m_arcache = ifc.m_arcache; // out
method Bit #(3) m_arprot = ifc.m_arprot; // out
method Bit #(4) m_arqos = ifc.m_arqos; // out
method Bit #(4) m_arregion = ifc.m_arregion; // out
method Bit #(wd_user) m_aruser = ifc.m_aruser; // out
method Action m_arready (Bool arready) = ifc.m_arready (arready); // in

// Rd Data channel
method Action m_rvalid (Bool rvalid, // in
Bit #(wd_id) rid, // in
Bit #(wd_data) rdata, // in
Bit #(2) rresp, // in
Bool rlast, // in
Bit #(wd_user) ruser); // in
ifc.m_rvalid (rvalid, rid, rdata, rresp, rlast, ruser);
endmethod
method Bool m_rready = ifc.m_rready; // out
endinterface;
endfunction

// ================================================================
// S-to-S interface transformer with address translation

function AXI4_S_IFC #(wd_id, wd_addr, wd_data, wd_user)
fv_AXI4_S_Address_Translator (Bool add_not_sub,
Bit #(wd_addr) addr_delta,
AXI4_S_IFC #(wd_id, wd_addr, wd_data, wd_user) ifc);

function Bit #(wd_addr) fv_addr_translate (Bit #(wd_addr) addr);
return (add_not_sub ? addr + addr_delta : addr - addr_delta);
endfunction

return interface AXI4_S_IFC
// Wr Addr channel
method Action m_awvalid (Bool awvalid,
Bit #(wd_id) awid,
Bit #(wd_addr) awaddr,
Bit #(8) awlen,
AXI4_Size awsize,
Bit #(2) awburst,
Bit #(1) awlock,
Bit #(4) awcache,
Bit #(3) awprot,
Bit #(4) awqos,
Bit #(4) awregion,
Bit #(wd_user) awuser);
ifc.m_awvalid (awvalid, awid,
fv_addr_translate (awaddr),
awlen, awsize, awburst,
awlock, awcache, awprot, awqos, awregion, awuser);
endmethod
method Bool m_awready = ifc.m_awready;

// Wr Data channel
method Action m_wvalid (Bool wvalid,
Bit #(wd_data) wdata,
Bit #(TDiv #(wd_data, 8)) wstrb,
Bool wlast,
Bit #(wd_user) wuser);
ifc.m_wvalid (wvalid, wdata, wstrb, wlast, wuser);
endmethod
method Bool m_wready = ifc.m_wready;

// Wr Response channel
method Bool m_bvalid = ifc.m_bvalid;
method Bit #(wd_id) m_bid = ifc.m_bid;
method Bit #(2) m_bresp = ifc.m_bresp;
method Bit #(wd_user) m_buser = ifc.m_buser;
method Action m_bready (Bool bready) = ifc.m_bready (bready);

// Rd Addr channel
method Action m_arvalid (Bool arvalid,
Bit #(wd_id) arid,
Bit #(wd_addr) araddr,
Bit #(8) arlen,
AXI4_Size arsize,
Bit #(2) arburst,
Bit #(1) arlock,
Bit #(4) arcache,
Bit #(3) arprot,
Bit #(4) arqos,
Bit #(4) arregion,
Bit #(wd_user) aruser);
ifc.m_arvalid (arvalid, arid,
fv_addr_translate (araddr),
arlen, arsize, arburst,
arlock, arcache, arprot, arqos, arregion, aruser);
endmethod
method Bool m_arready = ifc.m_arready;

// Rd Data channel
method Bool m_rvalid = ifc.m_rvalid;
method Bit #(wd_id) m_rid = ifc.m_rid;
method Bit #(wd_data) m_rdata = ifc.m_rdata;
method Bit #(2) m_rresp = ifc.m_rresp;
method Bool m_rlast = ifc.m_rlast;
method Bit #(wd_user) m_ruser = ifc.m_ruser;
method Action m_rready (Bool rready);
ifc.m_rready (rready);
endmethod
endinterface;
endfunction

// ================================================================

endpackage: AXI4_Addr_Translator
73 changes: 73 additions & 0 deletions Libraries/AMBA_Fabrics/AXI4/AXI4_ClockCrossing.bsv
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
// Copyright (c) 2020 Bluespec, Inc. All Rights Reserved
//
// SPDX-License-Identifier: BSD-3-Clause

package AXI4_ClockCrossing;

import Clocks ::*;
import AXI4_Types ::*;
import AXI4_Extra_Xactors ::*;
import Connectable ::*;
import Semi_FIFOF ::*;
import GetPut ::*;

// ================================================================

interface AXI4_ClockCrossing_IFC #(numeric type id_,
numeric type addr_,
numeric type data_,
numeric type user_);
interface AXI4_S_IFC #(id_, addr_, data_, user_) from_M;
interface AXI4_M_IFC #(id_, addr_, data_, user_) to_S;
endinterface

// ================================================================

module mkAXI4_ClockCrossing #(Clock clock_M,
Reset reset_M,
Clock clock_S,
Reset reset_S)
(AXI4_ClockCrossing_IFC #(id_, addr_, data_, user_));

SyncFIFOIfc #(AXI4_Wr_Addr #(id_, addr_, user_))
f_aw <- mkSyncFIFO (4, clock_M, reset_M, clock_S);

SyncFIFOIfc #(AXI4_Wr_Data #(data_, user_))
f_w <- mkSyncFIFO (4, clock_M, reset_M, clock_S);

SyncFIFOIfc #(AXI4_Wr_Resp #(id_, user_))
f_b <- mkSyncFIFO (4, clock_S, reset_S, clock_M);

SyncFIFOIfc #(AXI4_Rd_Addr #(id_, addr_, user_))
f_ar <- mkSyncFIFO (4, clock_M, reset_M, clock_S);

SyncFIFOIfc #(AXI4_Rd_Data #(id_, data_, user_))
f_r <- mkSyncFIFO (4, clock_S, reset_S, clock_M);

AXI4_S_IFC #(id_, addr_, data_, user_)
s_xactor <- mkAXI4_S_Xactor_3 (f_aw, f_w, f_b, f_ar, f_r,
clocked_by clock_M,
reset_by reset_M);

AXI4_M_IFC #(id_, addr_, data_, user_)
m_xactor <- mkAXI4_M_Xactor_3 (f_aw, f_w, f_b, f_ar, f_r,
clocked_by clock_S,
reset_by reset_S);

interface AXI4_S_IFC from_M = s_xactor;
interface AXI4_M_IFC to_S = m_xactor;
endmodule

// ----------------------------------------------------------------
// Same as above, with S-side using current-clock

module mkAXI4_ClockCrossingToCC #(Clock clock_M, Reset reset_M)
(AXI4_ClockCrossing_IFC #(id_, addr_, data_, user_));
let clock_S <- exposeCurrentClock;
let reset_S <- exposeCurrentReset;
let crossing <- mkAXI4_ClockCrossing (clock_M, reset_M, clock_S, reset_S);

return crossing;
endmodule

endpackage
Loading