-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add(apb): manager and subordinate (#28)
* (fix): Attempted to implement APB Manager (4/19) * (fix): Rewrote APB manager module; Partially wrote associated test bench * build: add apb subdir to dv CML Signed-off-by: rishyak <hello@rishyak.com> * fix: loop variable Signed-off-by: rishyak <hello@rishyak.com> * (fix): Added APB sub module * (fix): Implemented APB sub module and test bench --------- Signed-off-by: rishyak <hello@rishyak.com>
- Loading branch information
Showing
14 changed files
with
432 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Oops, something went wrong.