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

Sub attempt #28

Merged
merged 6 commits into from
May 29, 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
4 changes: 4 additions & 0 deletions dv/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ if(TEST_GENERIC OR TEST_ALL)
add_subdirectory(generic)
endif()

if(TEST_APB OR TEST_ALL)
add_subdirectory(apb)
endif()

nyu_link_sv(tests PRIVATE amba)
nyu_target_verilate(tests
TOP_MODULES ${TOP_MODULES}
Expand Down
64 changes: 64 additions & 0 deletions dv/apb/APBManager/APBManager.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include <catch2/catch_test_macros.hpp>
#include <NyuTestUtil.hpp>

#include <VAPBManager_tl.h>

// Verify all pass-thrus into bus
TEST_CASE("APBManager, bus-to-device pass-thru") {
VAPBManager_tl& bm {nyu::getDUT<VAPBManager_tl>()};
nyu::reset(bm);
for (std::uint8_t i {0}; i < 2; ++i) {
bm.localSel = i;
nyu::eval(bm);
REQUIRE(bm.bus_selectors == i);
}
for (std::uint8_t i {0}; i < 16; ++i) {
bm.mgr_prot = i;
bm.mgr_wStrb = i;
nyu::eval(bm);
REQUIRE(bm.bus_prot == i);
REQUIRE(bm.bus_strb == i);
}
for (std::uint32_t i {1}; i; i <<= 1) {
bm.mgr_wData = i;
bm.mgr_addr = i;
nyu::eval(bm);
REQUIRE(bm.bus_wData == i);
REQUIRE(bm.bus_addr == i);
REQUIRE(bm.localAddr == i);
}
// Double-check how to handle localSel & localAddr here
}

// Verify all pass-thrus from bus
TEST_CASE("APBManager, device-to-bus pass-thru") {
VAPBManager_tl& bm {nyu::getDUT<VAPBManager_tl>()};
nyu::reset(bm);
for (std::uint8_t i {0}; i < 2; ++i) {
bm.bus_ready = i;
bm.bus_subError = i;
nyu::eval(bm);
REQUIRE(bm.mgr_busy == !i);
REQUIRE(bm.mgr_error == i);
}
for (std::uint32_t i {1}; i; i <<= 1) {
bm.bus_rData = i;
nyu::eval(bm);
REQUIRE(bm.mgr_rData == i);
}
}

// Verify all logic implemented
TEST_CASE("APBManager, logical assigns"){
VAPBManager_tl& bm {nyu::getDUT<VAPBManager_tl>()};
nyu::reset(bm);
for (std::uint8_t i {0}; i < 2; ++i) {
for (std::uint8_t j {0}; j < 2; ++j) {
bm.mgr_wEn = i;
bm.mgr_rEn = j;
nyu::eval(bm);
REQUIRE(bm.bus_write == (i && !j));
REQUIRE(bm.bus_enable == (i ^ j));
}
}
}
89 changes: 89 additions & 0 deletions dv/apb/APBManager/APBManager_tl.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
module APBManager_tl #(
DataWidth = 32,
AddrWidth = 32,
ProtWidth = 4,
PrphNum = 1
) (
input clk,
input nReset,

// Managing Device signals
input mgr_wEn,
input mgr_rEn,
input [AddrWidth - 1:0] mgr_addr,
input [DataWidth - 1:0] mgr_wData,
input [DataWidth/8 - 1:0] mgr_wStrb,
input [ProtWidth - 1:0] mgr_prot,

output logic [DataWidth - 1:0] mgr_rData,
output logic mgr_error,
output logic mgr_busy,

// Bus signals
// assigns values to it c++ - input to sv model
// read values from it c++ - output to sv model


input bus_ready,
input [DataWidth - 1:0] bus_rData,
input bus_subError,

output logic [PrphNum - 1:0] bus_selectors,
output [ProtWidth - 1:0] bus_prot,
output logic bus_enable,
output logic bus_write,
output [AddrWidth - 1:0] bus_addr,
output logic [DataWidth - 1:0] bus_wData,
output logic [DataWidth/8 - 1:0] bus_strb,

// Extraneous signals (source unknown)
// Adjust localSel and localAddr -> Ask Vito
input [PrphNum - 1:0] localSel,
output [AddrWidth-1:0] localAddr
);

GenericBus_if #(DataWidth, AddrWidth, ProtWidth) mgr (
clk,
nReset
);

always_comb begin
mgr.wEn = mgr_wEn;
mgr.rEn = mgr_rEn;
mgr.addr = mgr_addr;
mgr.wData = mgr_wData;
mgr.wStrb = mgr_wStrb;
mgr.prot = mgr_prot;

mgr_rData = mgr.rData;
mgr_error = mgr.error;
mgr_busy = mgr.busy;
end

APBCommon_if #(DataWidth, AddrWidth, PrphNum) bus (
clk,
nReset
);

always_comb begin
bus_write = bus.write;
bus_enable = bus.enable;
bus_wData = bus.wData;
bus_strb = bus.strb;
bus_selectors = bus.selectors;
bus_prot = bus.prot;
bus_addr = bus.addr;

bus.rData = bus_rData;
bus.subError = bus_subError;
bus.ready = bus_ready;
end

APBManager bus_mgr (
mgr,
bus,
localSel,
localAddr
);

endmodule
6 changes: 6 additions & 0 deletions dv/apb/APBManager/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
target_sources(tests PRIVATE APBManager.cpp)
nyu_add_sv(tests
APBManager_tl.sv
)
list(APPEND TOP_MODULES APBManager_tl)
set(TOP_MODULES ${TOP_MODULES} PARENT_SCOPE)
68 changes: 68 additions & 0 deletions dv/apb/APBSubordinate/APBSubordinate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
#include <catch2/catch_test_macros.hpp>
#include <NyuTestUtil.hpp>

#include <VAPBSubordinate_tl.h>


void logical_test(VAPBSubordinate_tl& bs, uint8_t sel) {
nyu::reset(bs);
const std::uint32_t base_addr {0x100};
bs.bus_selectors = sel;
for (std::uint8_t i {0}; i < 2; ++i) {
for (std::uint8_t j {0}; j < 2; ++j) {
bs.bus_write = i;
bs.bus_enable = j;
nyu::eval(bs);
REQUIRE(bs.sub_wEn == (sel ? (i && j) : 0));
REQUIRE(bs.sub_rEn == (sel ? (!i && j) : 0));
}
}
for (std::uint32_t i {1}; i; i <<= 1) {
bs.bus_addr = base_addr + i;
nyu::eval(bs);
REQUIRE(bs.sub_addr == (sel ? i : 0));
}
}

// bus-to-device pass-thru
TEST_CASE("APBSubordinate, bus-to-device pass-thru") {
VAPBSubordinate_tl& bs {nyu::getDUT<VAPBSubordinate_tl>()};
nyu::reset(bs);
for (std::uint8_t i {0}; i < 16; ++i) {
bs.bus_prot = i;
bs.bus_strb = i;
nyu::eval(bs);
REQUIRE(bs.sub_prot == i);
REQUIRE(bs.sub_wStrb == i);
}
for (std::uint32_t i {1}; i; i <<= 1) {
bs.bus_wData = i;
nyu::eval(bs);
REQUIRE(bs.sub_wData == i);
}
}

// device-to-bus pass-thru
TEST_CASE("APBSubordinate, device-to-bus pass-thru") {
VAPBSubordinate_tl& bs {nyu::getDUT<VAPBSubordinate_tl>()};
nyu::reset(bs);
for (std::uint8_t i{0}; i < 2; ++i) {
bs.sub_error = i;
bs.sub_busy = i;
nyu::eval(bs);
REQUIRE(bs.bus_subError == i);
REQUIRE(bs.bus_ready == !i);
}
for (std::uint32_t i{1}; i; i <<= 1) {
bs.sub_rData = i;
nyu::eval(bs);
REQUIRE(bs.bus_rData == i);
}
}

// logical
TEST_CASE("APBSubordinate, logical") {
VAPBSubordinate_tl& bs {nyu::getDUT<VAPBSubordinate_tl>()};
logical_test(bs, 0);
logical_test(bs, 1);
}
77 changes: 77 additions & 0 deletions dv/apb/APBSubordinate/APBSubordinate_tl.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
module APBSubordinate_tl #(
DataWidth = 32,
AddrWidth = 32,
ProtWidth = 4,
PrphNum = 1
) (
input clk,
input nReset,

output logic sub_wEn,
output logic sub_rEn,
output logic [AddrWidth - 1:0] sub_addr,
output logic [DataWidth - 1:0] sub_wData,
output logic [DataWidth/8 - 1:0] sub_wStrb,
output logic [ProtWidth - 1:0] sub_prot,

input [DataWidth - 1:0] sub_rData,
input sub_error,
input sub_busy,

input bus_write,
input bus_enable,
input [AddrWidth - 1:0] bus_addr,
input [DataWidth - 1:0] bus_wData,
input [DataWidth/8 - 1:0] bus_strb,
input [ProtWidth - 1:0] bus_prot,
input [PrphNum - 1:0] bus_selectors,

output logic [DataWidth - 1:0] bus_rData,
output logic bus_subError,
output logic bus_ready

);

GenericBus_if #(DataWidth, AddrWidth, ProtWidth) sub (
clk,
nReset
);

always_comb begin
sub_wEn = sub.wEn;
sub_rEn = sub.rEn;
sub_addr = sub.addr;
sub_wData = sub.wData;
sub_wStrb = sub.wStrb;
sub_prot = sub.prot;

sub.rData = sub_rData;
sub.error = sub_error;
sub.busy = sub_busy;
end

APBCommon_if #(DataWidth, AddrWidth, PrphNum) bus (
clk,
nReset
);

always_comb begin
bus.write = bus_write;
bus.enable = bus_enable;
bus.addr = bus_addr;
bus.wData = bus_wData;
bus.strb = bus_strb;
bus.prot = bus_prot;
bus.selectors = bus_selectors;

bus_rData = bus.rData;
bus_subError = bus.subError;
bus_ready = bus.ready;
end

APBSubordinate #(32'h100, 32'hFFFFFF00) bus_sub (
sub,
bus
);

endmodule
6 changes: 6 additions & 0 deletions dv/apb/APBSubordinate/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
target_sources(tests PRIVATE APBSubordinate.cpp)
nyu_add_sv(tests
APBSubordinate_tl.sv
)
list(APPEND TOP_MODULES APBSubordinate_tl)
set(TOP_MODULES ${TOP_MODULES} PARENT_SCOPE)
4 changes: 4 additions & 0 deletions dv/apb/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
add_subdirectory(APBManager)
add_subdirectory(APBSubordinate)

set(TOP_MODULES ${TOP_MODULES} PARENT_SCOPE)
36 changes: 36 additions & 0 deletions rtl/apb/devices/APBManager.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
@brief Manager that uses the AMBA APB protocol directly as the transmission
protocol

@input device managing device
@input bus bus to managed
*/

module APBManager (
GenericBus_if device,
APBCommon_if bus,
input [bus.PrphNum - 1:0] localSel,
output [bus.AddrWidth-1:0] localAddr
);
always_comb begin
device.rData = bus.rData;
bus.wData = device.wData;
bus.addr = device.addr;
localAddr = device.addr;
bus.selectors = localSel;
end
// Always_comb must have something for every situation
always_comb begin
bus.prot = device.prot;
bus.strb = device.wStrb;
bus.write = device.wEn && !device.rEn;
bus.enable = device.wEn ^ device.rEn;
end
// wEn and rEn both being high is meaningless in generic -> check this in test bench
// Generic pov -> device tells you it's done by wEn going low -> done writing
// Assume for generic, rEn goes up for single cycle
always_comb begin
device.busy = !bus.ready;
device.error = bus.subError;
end
endmodule
Loading