add in bus architecture prototypes from the last few days

This commit is contained in:
Fischer Moseley 2023-02-28 15:11:11 -05:00
parent f3710d4cbc
commit e55d919098
9 changed files with 855 additions and 136 deletions

130
src/manta/bridge_rx.v Normal file
View File

@ -0,0 +1,130 @@
`default_nettype none
`timescale 1ns/1ps
module bridge_rx(
input wire clk,
input wire rst,
input wire[7:0] axiid,
input wire axiiv,
output reg[15:0] req_addr,
output reg[15:0] req_data,
output reg req_rw,
output reg req_valid,
input wire req_ready
);
parameter ADDR_WIDTH = 0;
parameter DATA_WIDTH = 0;
localparam PREAMBLE = 8'h4D;
localparam CR = 8'h0D;
localparam LF = 8'h0A;
localparam ACQUIRE = 0;
localparam TRANSMIT = 1;
localparam ERROR = 2;
reg [1:0] state;
reg [3:0] bytes_received;
// no global resets!
initial begin
req_addr = 0;
req_data = 0;
req_rw = 0;
req_valid = 0;
bytes_received = 0;
state = ACQUIRE;
end
reg [3:0] axiid_decoded;
reg axiid_is_0_thru_9;
reg axiid_is_A_thru_F;
always @(*) begin
axiid_is_0_thru_9 = (axiid >= 8'h30) & (axiid <= 8'h39);
axiid_is_A_thru_F = (axiid >= 8'h41) & (axiid <= 8'h46);
if (axiid_is_0_thru_9) axiid_decoded = axiid - 8'h30;
else if (axiid_is_A_thru_F) axiid_decoded = axiid - 8'h41 + 'd10;
else axiid_decoded = 0;
end
always @(posedge clk) begin
if (state == ACQUIRE) begin
if(axiiv) begin
if (bytes_received == 0) begin
if(axiid == PREAMBLE) bytes_received <= 1;
end
else if( (bytes_received >= 1) & (bytes_received <= 4) ) begin
// only advance if byte is valid hex digit
if(axiid_is_0_thru_9 | axiid_is_A_thru_F) begin
req_addr <= (req_addr << 4) | axiid_decoded;
bytes_received <= bytes_received + 1;
end
else state <= ERROR;
end
else if( bytes_received == 5) begin
if( (axiid == CR) | (axiid == LF)) begin
req_valid <= 1;
req_rw = 0;
bytes_received <= 0;
state <= TRANSMIT;
end
else if (axiid_is_0_thru_9 | axiid_is_A_thru_F) begin
bytes_received <= bytes_received + 1;
req_data <= (req_data << 4) | axiid_decoded;
end
else state <= ERROR;
end
else if ( (bytes_received >= 6) & (bytes_received <= 8) ) begin
if (axiid_is_0_thru_9 | axiid_is_A_thru_F) begin
req_data <= (req_data << 4) | axiid_decoded;
bytes_received <= bytes_received + 1;
end
else state <= ERROR;
end
else if (bytes_received == 9) begin
bytes_received <= 0;
if( (axiid == CR) | (axiid == LF)) begin
req_valid <= 1;
req_rw <= 1;
state <= TRANSMIT;
end
else state <= ERROR;
end
end
end
else if (state == TRANSMIT) begin
if(req_ready) begin
req_valid <= 0;
state <= ACQUIRE;
end
if(axiiv) begin
if ( (axiid != CR) & (axiid != LF)) begin
req_valid <= 0;
state <= ERROR;
end
end
end
end
endmodule
`default_nettype wire

93
src/manta/bridge_tx.v Normal file
View File

@ -0,0 +1,93 @@
`default_nettype none
`timescale 1ns/1ps
module bridge_tx(
input wire clk,
output reg [7:0] axiod,
output reg axiov,
input wire axior,
input wire [15:0] res_data,
input wire res_valid,
output reg res_ready
);
parameter ADDR_WIDTH = 0;
parameter DATA_WDITH = 0;
localparam PREAMBLE = 8'h4D;
localparam CR = 8'h0D;
localparam LF = 8'h0A;
reg [3:0] bytes_transmitted;
reg [15:0] buffer;
initial begin
axiod = 0;
axiov = 0;
res_ready = 1;
bytes_transmitted = 0;
buffer = 0;
end
always @(posedge clk) begin
if (res_ready) begin
if(res_valid) begin
buffer <= res_data;
res_ready <= 0;
bytes_transmitted <= 0;
axiod <= PREAMBLE;
axiov <= 1;
end
end
else begin
if (bytes_transmitted == 0) begin
if(axior) bytes_transmitted <= 1;
end
if (bytes_transmitted == 1) begin
axiod <= (buffer[15:12] < 10) ? (buffer[15:12] + 8'h30) : (buffer[15:12] + 8'h41 - 'd10);
if (axior) bytes_transmitted <= 2;
end
else if(bytes_transmitted == 2) begin
axiod <= (buffer[11:8] < 10) ? (buffer[11:8] + 8'h30) : (buffer[11:8] + 8'h41 - 'd10);
if (axior) bytes_transmitted <= 3;
end
else if(bytes_transmitted == 3) begin
axiod <= (buffer[7:4] < 10) ? (buffer[7:4] + 8'h30) : (buffer[7:4] + 8'h41 - 'd10);
if (axior) bytes_transmitted <= 4;
end
else if(bytes_transmitted == 4) begin
axiod <= (buffer[3:0] < 10) ? (buffer[3:0] + 8'h30) : (buffer[3:0] + 8'h41 - 'd10);
if (axior) bytes_transmitted <= 5;
end
else if(bytes_transmitted == 5) begin
axiod <= 8'h0D;
if (axior) bytes_transmitted <= 6;
end
else if(bytes_transmitted == 6) begin
axiod <= 8'h0A;
if (axior) begin
axiov <= 0;
bytes_transmitted <= 7;
end
end
else if(bytes_transmitted == 7) begin
if(axior) begin
res_ready <= 1;
bytes_transmitted <= 0;
end
end
end
end
endmodule
`default_nettype wire

70
src/manta/lut_ram.v Normal file
View File

@ -0,0 +1,70 @@
`default_nettype none
`timescale 1ns/1ps
module lut_ram(
input wire clk,
// input port
input wire req_addr_i,
input wire req_data_i,
input wire req_rw_i,
input wire req_valid_i,
output reg req_ready_o
input wire res_data_i,
input wire res_valid_i,
output reg res_ready_o
// output port
output reg req_addr_o,
output reg req_data_o,
output reg req_rw_o,
output reg req_valid_o,
input wire req_ready_i,
output reg res_data_o,
output reg res_valid_o,
input wire res_ready_i
);
localparam BASE_ADDR = 0;
localparam DEPTH = 8;
localparam TOP_ADDR = BASE_ADDR + DEPTH - 1;
reg [15:0] [DEPTH-1:0] mem;
initial begin
req_ready_o = 1;
end
always @(posedge clk) begin
if( (req_addr_i < BASE_ADDR) || (req_addr_i > TOP_ADDR) ) begin
req_addr_o <= req_addr_i;
req_data_o <= req_data_i;
req_rw_o <= req_rw_i;
req_valid_o <= req_valid_i;
req_ready_o <= req_ready_i;
res_data_o <= res_data_i;
res_valid_o <= res_valid_i;
res_ready_o <= res_ready_i;
end
else begin
req_ready <= 1;
if (req_valid_i) begin
if (req_rw_i) mem[req_addr_i - BASE_ADDR] <= req_data_i;
else begin
end
end
end
end
endmodule
`default_nettype wire

View File

@ -6,35 +6,32 @@ module uart_rx(
input wire rst,
input wire rxd,
output logic [DATA_WIDTH - 1:0] data,
output logic ready,
output logic busy
output reg [DATA_WIDTH - 1:0] axiod,
output reg axiov
);
// Just going to stick to 8N1 for now, we'll come back and
// parameterize this later.
parameter DATA_WIDTH = 8;
parameter CLK_FREQ_HZ = 100_000_000;
parameter BAUDRATE = 115200;
parameter DATA_WIDTH = 0;
parameter CLK_FREQ_HZ = 0;
parameter BAUDRATE = 0;
localparam PRESCALER = CLK_FREQ_HZ / BAUDRATE;
localparam BAUD_PERIOD = CLK_FREQ_HZ / BAUDRATE;
logic [$clog2(PRESCALER) - 1:0] baud_counter;
logic [$clog2(DATA_WIDTH + 2):0] bit_index;
logic [DATA_WIDTH + 2 : 0] data_buf;
reg [$clog2(BAUD_PERIOD) - 1:0] baud_counter;
reg [$clog2(DATA_WIDTH + 2):0] bit_index;
reg [DATA_WIDTH + 2 : 0] data_buf;
logic prev_rxd;
reg prev_rxd;
reg busy;
always_ff @(posedge clk) begin
prev_rxd <= rxd;
ready <= 0;
baud_counter <= (baud_counter == PRESCALER - 1) ? 0 : baud_counter + 1;
axiov <= 0;
baud_counter <= (baud_counter == BAUD_PERIOD - 1) ? 0 : baud_counter + 1;
// reset logic
if(rst) begin
bit_index <= 0;
data <= 0;
axiod <= 0;
busy <= 0;
baud_counter <= 0;
end
@ -48,7 +45,7 @@ module uart_rx(
// if we're actually receiving
else if (busy) begin
if (baud_counter == PRESCALER / 2) begin
if (baud_counter == BAUD_PERIOD / 2) begin
data_buf[bit_index] <= rxd;
bit_index <= bit_index + 1;
@ -58,8 +55,8 @@ module uart_rx(
if (rxd && ~data_buf[0]) begin
data <= data_buf[DATA_WIDTH : 1];
ready <= 1;
axiod <= data_buf[DATA_WIDTH : 1];
axiov <= 1;
end
end
end

View File

@ -1,39 +1,39 @@
`default_nettype none
`timescale 1ns / 1ps
module uart_tx(
input wire clk,
input wire rst,
input wire [DATA_WIDTH-1:0] data,
input wire start,
output logic busy,
output logic txd
input wire [DATA_WIDTH-1:0] axiid,
input wire axiiv,
output reg axiir,
output reg txd
);
// Just going to stick to 8N1 for now, we'll come back and
// parameterize this later.
parameter DATA_WIDTH = 8;
parameter CLK_FREQ_HZ = 100_000_000;
parameter BAUDRATE = 115200;
parameter DATA_WIDTH = 0;
parameter CLK_FREQ_HZ = 0;
parameter BAUDRATE = 0;
localparam PRESCALER = CLK_FREQ_HZ / BAUDRATE;
localparam BAUD_PERIOD = CLK_FREQ_HZ / BAUDRATE;
logic [$clog2(PRESCALER) - 1:0] baud_counter;
logic [$clog2(DATA_WIDTH + 2):0] bit_index;
logic [DATA_WIDTH - 1:0] data_buf;
reg busy;
assign axiir = ~busy;
reg [$clog2(BAUD_PERIOD) - 1:0] baud_counter;
reg [$clog2(DATA_WIDTH + 2):0] bit_index;
reg [DATA_WIDTH - 1:0] data_buf;
// make secondary logic for baudrate
always_ff @(posedge clk) begin
always @(posedge clk) begin
if(rst) baud_counter <= 0;
else begin
baud_counter <= (baud_counter == PRESCALER - 1) ? 0 : baud_counter + 1;
baud_counter <= (baud_counter == BAUD_PERIOD - 1) ? 0 : baud_counter + 1;
end
end
always_ff @(posedge clk) begin
always @(posedge clk) begin
// reset logic
if(rst) begin
@ -45,9 +45,9 @@ module uart_tx(
// enter transmitting state logic
// don't allow new requests to interrupt current
// transfers
if(start && ~busy) begin
if(axiiv && ~busy) begin
busy <= 1;
data_buf <= data;
data_buf <= axiid;
end

View File

@ -1,96 +0,0 @@
`default_nettype none
`define IDLE 0
`define RUN 1
module uplink(
input wire clk,
input wire rst,
input wire start,
output wire busy,
/* Begin autogenerated probe definitions */
output wire alice,
output wire [2:0] bob,
output wire charlotte,
output wire [3:0] donovan
/* End autogenerated probe definitions */
);
/*
this works in a very simple way - all it does is chill
in the idle state, until a request to start uplinking is
received. when that happens, it'll start dumping things
from the port until the BRAM is empty, and then that's it.
this dumping happens with the trigger condition - the clock
cycle that the triggr goes high on, we should output data.
or have the option to, with some kind of holdoff.
oh wait this might be a little hard since we've got the two
clock cycles of latency on the BRAM, so we actually need to
preload the first two values of the bram into registers so
when it's time to go
actually it's probably worth thinking more about how useful
this would acatully be, because right now i'm not seeing too
many situations where i'd want to use this. and we can always
come back to it
*/
parameter WIDTH = 0;
parameter DEPTH = 0;
localparam AW = $clog2(DEPTH);
logic [AW:0] read_pointer;
logic state;
always_ff @(posedge clk) begin
if(rst) begin
state <= `IDLE
read_pointer <= 0;
end
else begin
if(state == `IDLE) begin
// do nothing, just wait for trigger condition
if(start) state <= `RUN;
end
if(state == `RUN) begin
end
end
end
xilinx_true_dual_port_read_first_2_clock_ram #(
.RAM_WIDTH(),
.RAM_DEPTH(),
.RAM_PERFORMANCE("HIGH PERFORMANCE")
) buffer (
// write port (currently unused)
.clka(clk),
.rsta(rst),
.ena(1),
.addra(0),
.dina(0),
.wea(0),
.regcea(1),
.douta(),
// read port
.clkb(clk),
.rstb(rst),
.enb(1),
.addrb(read_pointer),
.dinb(),
.web(0),
.regceb(1),
.doutb(data_out));
endmodule
`default_nettype wire

287
test/bridge_rx_tb.sv Normal file
View File

@ -0,0 +1,287 @@
`default_nettype none
`timescale 1ns/1ps
`define CP 10
`define HCP 5
`define SEND_MESSAGE(MESSAGE) \
uart_rx_axiov = 1; \
for(int i=0; i < $size(MESSAGE); i++) begin \
uart_rx_axiod = MESSAGE[i]; \
#`CP; \
end \
uart_rx_axiov = 0; \
module bridge_rx_tb;
// https://www.youtube.com/watch?v=WCOAr-96bGc
//boilerplate
logic clk;
logic rst;
string message;
integer test_num;
// uart inputs and outputs
logic rxd;
logic [7:0] uart_rx_axiod;
logic uart_rx_axiov;
// the parameter will all get filled out in manta's big instantiator thing hehehee
parameter ADDR_WIDTH = 16; // $clog2( how much memory we need rounded up to the nearest 8 )
parameter DATA_WIDTH = 16;
// request bus, gets connected to uart_rx (through a FSM)
logic [ADDR_WIDTH-1:0] req_addr;
logic [DATA_WIDTH-1:0] req_data;
logic req_rw;
logic req_valid;
logic req_ready;
bridge_rx bridge_rx_uut(
.clk(clk),
.rst(rst),
// connect to uart_rx
.axiid(uart_rx_axiod),
.axiiv(uart_rx_axiov),
.req_addr(req_addr),
.req_data(req_data),
.req_rw(req_rw),
.req_valid(req_valid),
.req_ready(req_ready));
always begin
#`HCP
clk = !clk;
end
initial begin
$dumpfile("bridge_rx.vcd");
$dumpvars(0, bridge_rx_tb);
// setup and reset
clk = 0;
rst = 0;
uart_rx_axiod = 0;
uart_rx_axiov = 0;
req_ready = 1;
test_num = 0;
#`CP
rst = 1;
#`CP
rst = 0;
/* ==== Test 1 Begin ==== */
$display("\n=== test 1: transmit M12345678(CR)(LF) for baseline functionality ===");
test_num = 1;
message = {"M12345678", 8'h0D, 8'h0A};
`SEND_MESSAGE(message)
assert(req_addr == 16'h1234) else $error("incorrect addr!");
assert(req_data == 16'h5678) else $error("incorrect data!");
assert(req_rw == 1) else $error("incorrect rw!");
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission");
#(10*`CP);
/* ==== Test 1 End ==== */
/* ==== Test 2 Begin ==== */
$display("\n=== test 2: transmit MDEADBEEF(CR)(LF) for proper state reset ===");
test_num = 2;
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission");
message = {"MDEADBEEF", 8'h0D, 8'h0A};
`SEND_MESSAGE(message)
assert(req_addr == 16'hDEAD) else $error("incorrect addr!");
assert(req_data == 16'hBEEF) else $error("incorrect data!");
assert(req_rw == 1) else $error("incorrect rw!");
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission");
#(10*`CP);
/* ==== Test 2 End ==== */
/* ==== Test 3 Begin ==== */
$display("\n=== test 3: transmit MBABE(CR)(LF) for baseline functionality ===");
test_num = 3;
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission");
message = {"MBABE", 8'h0D, 8'h0A};
`SEND_MESSAGE(message)
assert(req_addr == 16'hBABE) else $error("incorrect addr!");
assert(req_rw == 0) else $error("incorrect rw!");
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission");
#(10*`CP);
/* ==== Test 3 End ==== */
/* ==== Test 4 Begin ==== */
$display("\n=== test 4: transmit M0000(CR) for EOL insensitivity ===");
test_num = 4;
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission");
message = {"M0000", 8'h0D};
`SEND_MESSAGE(message)
assert(req_addr == 16'h0000) else $error("incorrect addr!");
assert(req_rw == 0) else $error("incorrect rw!");
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission");
#(10*`CP);
/* ==== Test 4 End ==== */
/* ==== Test 5 Begin ==== */
$display("\n=== test 5: transmit M1234(LF) for EOL insensitivity ===");
test_num = 5;
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission");
message = {"M1234", 8'h0D};
`SEND_MESSAGE(message)
assert(req_addr == 16'h1234) else $error("incorrect addr!");
assert(req_rw == 0) else $error("incorrect rw!");
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission");
#(10*`CP);
/* ==== Test 5 End ==== */
/* ==== Test 6 Begin ==== */
$display("\n=== test 6: transmit MF00DBEEF(CR) for EOL insensitivity ===");
test_num = 6;
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission");
message = {"MF00DBEEF", 8'h0D};
`SEND_MESSAGE(message)
assert(req_addr == 16'hF00D) else $error("incorrect addr!");
assert(req_data == 16'hBEEF) else $error("incorrect data!");
assert(req_rw == 1) else $error("incorrect rw!");
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission");
#(10*`CP);
/* ==== Test 6 End ==== */
/* ==== Test 7 Begin ==== */
$display("\n=== test 7: transmit MB0BACAFE(LF) for EOL insensitivity ===");
test_num = 7;
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission");
message = {"MB0BACAFE", 8'h0D};
`SEND_MESSAGE(message)
assert(req_addr == 16'hB0BA) else $error("incorrect addr!");
assert(req_data == 16'hCAFE) else $error("incorrect data!");
assert(req_rw == 1) else $error("incorrect rw!");
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state after transmission");
#(10*`CP);
/* ==== Test 7 End ==== */
/* ==== Test 8 Begin ==== */
$display("\n\nIntentionally bad messages:");
$display("\n=== test 8: transmit MABC(CR)(LF) for message length ===");
test_num = 8;
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission");
message = {"MABC", 8'h0D, 8'h0A};
`SEND_MESSAGE(message)
assert(req_valid == 0) else $error("valid asserted for bad message");
assert(bridge_rx_uut.state == bridge_rx_uut.ERROR) else $error("not in error state after transmission");
#(10*`CP);
/* ==== Test 8 End ==== */
/* ==== Test 9 Begin ==== */
$display("\n=== test 9: transmit M12345(CR)(LF) for message length ===");
test_num = 9;
bridge_rx_uut.state = bridge_rx_uut.ACQUIRE;
bridge_rx_uut.bytes_received = 0;
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission");
message = {"MABC", 8'h0D, 8'h0A};
`SEND_MESSAGE(message)
assert(req_valid == 0) else $error("valid asserted for bad message");
assert(bridge_rx_uut.state == bridge_rx_uut.ERROR) else $error("not in error state after transmission");
#(10*`CP);
/* ==== Test 9 End ==== */
/* ==== Test 10 Begin ==== */
$display("\n=== test 10: transmit M(CR)(LF) for message length ===");
test_num = 10;
bridge_rx_uut.state = bridge_rx_uut.ACQUIRE;
bridge_rx_uut.bytes_received = 0;
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission");
message = {"MABC", 8'h0D, 8'h0A};
`SEND_MESSAGE(message)
assert(req_valid == 0) else $error("valid asserted for bad message");
assert(bridge_rx_uut.state == bridge_rx_uut.ERROR) else $error("not in error state after transmission");
#(10*`CP);
/* ==== Test 10 End ==== */
/* ==== Test 11 Begin ==== */
$display("\n=== test 11: transmit M123456789101112131415161718191201222(CR)(LF) for message length ===");
test_num = 11;
bridge_rx_uut.state = bridge_rx_uut.ACQUIRE;
bridge_rx_uut.bytes_received = 0;
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission");
message = {"MABC", 8'h0D, 8'h0A};
`SEND_MESSAGE(message)
assert(req_valid == 0) else $error("valid asserted for bad message");
assert(bridge_rx_uut.state == bridge_rx_uut.ERROR) else $error("not in error state after transmission");
#(10*`CP);
/* ==== Test 11 End ==== */
/* ==== Test 12 Begin ==== */
$display("\n=== test 12: transmit MABCG(CR)(LF) for invalid characters ===");
test_num = 12;
bridge_rx_uut.state = bridge_rx_uut.ACQUIRE;
bridge_rx_uut.bytes_received = 0;
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission");
message = {"MABCG", 8'h0D, 8'h0A};
`SEND_MESSAGE(message)
assert(req_valid == 0) else $error("valid asserted for bad message");
assert(bridge_rx_uut.state == bridge_rx_uut.ERROR) else $error("not in error state after transmission");
#(10*`CP);
/* ==== Test 12 End ==== */
/* ==== Test 13 Begin ==== */
$display("\n=== test 13: transmit MABC[]()##*@(CR)(LF) for invalid characters and message length ===");
test_num = 13;
bridge_rx_uut.state = bridge_rx_uut.ACQUIRE;
bridge_rx_uut.bytes_received = 0;
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission");
message = {"MABC[]()##*@", 8'h0D, 8'h0A};
`SEND_MESSAGE(message)
assert(req_valid == 0) else $error("valid asserted for bad message");
assert(bridge_rx_uut.state == bridge_rx_uut.ERROR) else $error("not in error state after transmission");
#(10*`CP);
/* ==== Test 13 End ==== */
/* ==== Test 14 Begin ==== */
$display("\n=== test 14: transmit M(CR)(LF) for message length ===");
test_num = 14;
bridge_rx_uut.state = bridge_rx_uut.ACQUIRE;
bridge_rx_uut.bytes_received = 0;
assert(bridge_rx_uut.state != bridge_rx_uut.ERROR) else $error("in error state before transmission");
message = {"M", 8'h0D, 8'h0A};
`SEND_MESSAGE(message)
assert(req_valid == 0) else $error("valid asserted for bad message");
assert(bridge_rx_uut.state == bridge_rx_uut.ERROR) else $error("not in error state after transmission");
#(10*`CP);
/* ==== Test 14 End ==== */
$finish();
end
endmodule
`default_nettype wire

132
test/bridge_tx_tb.sv Normal file
View File

@ -0,0 +1,132 @@
`default_nettype none
`timescale 1ns/1ps
`define CP 10
`define HCP 5
module bridge_tx_tb;
// https://www.youtube.com/watch?v=WCOAr-96bGc
//boilerplate
logic clk;
logic rst;
integer test_num;
// uart_tx <--> tb signals
logic txd;
// uart_tx <--> bridge_tx signals
logic [7:0] axid;
logic axiv;
logic axir;
// bridge_tx <--> tb signals
logic res_valid;
logic res_ready;
logic [15:0] res_data;
uart_tx #(
.DATA_WIDTH(8),
.CLK_FREQ_HZ(100_000_000),
.BAUDRATE(115200))
uart_tx_uut (
.clk(clk),
.rst(rst),
.txd(txd),
.axiid(axid),
.axiiv(axiv),
.axiir(axir));
bridge_tx bridge_tx_uut(
.clk(clk),
.axiod(axid),
.axiov(axiv),
.axior(axir),
.res_valid(res_valid),
.res_ready(res_ready),
.res_data(res_data));
always begin
#`HCP
clk = !clk;
end
initial begin
$dumpfile("bridge_tx.vcd");
$dumpvars(0, bridge_tx_tb);
// setup and reset
clk = 0;
rst = 0;
test_num = 0;
res_valid = 0;
res_data = 0;
#`CP
rst = 1;
#`CP
rst = 0;
#(10*`CP);
/* ==== Test 1 Begin ==== */
$display("\n=== test 1: receive 0x0123 for baseline functionality ===");
test_num = 1;
res_data = 16'h0123;
res_valid = 1;
#`CP;
assert(res_ready == 0) else $error("invalid handshake: res_ready held high for more than one clock cycle");
res_valid = 0;
#(100000*`CP);
/* ==== Test 1 End ==== */
/* ==== Test 2 Begin ==== */
$display("\n=== test 2: receive 0x4567 for baseline functionality ===");
test_num = 2;
res_data = 16'h4567;
res_valid = 1;
#`CP;
assert(res_ready == 0) else $error("invalid handshake: res_ready held high for more than one clock cycle");
res_valid = 0;
#(100000*`CP);
/* ==== Test 2 End ==== */
/* ==== Test 3 Begin ==== */
$display("\n=== test 3: receive 0x89AB for baseline functionality ===");
test_num = 3;
res_data = 16'h89AB;
res_valid = 1;
#`CP;
assert(res_ready == 0) else $error("invalid handshake: res_ready held high for more than one clock cycle");
res_valid = 0;
#(100000*`CP);
/* ==== Test 3 End ==== */
/* ==== Test 4 Begin ==== */
$display("\n=== test 4: receive 0xCDEF for baseline functionality ===");
test_num = 4;
res_data = 16'hCDEF;
res_valid = 1;
#`CP;
assert(res_ready == 0) else $error("invalid handshake: res_ready held high for more than one clock cycle");
res_valid = 0;
#(100000*`CP);
/* ==== Test 4 End ==== */
$finish();
end
endmodule
`default_nettype wire

106
test/bus_tb.sv Normal file
View File

@ -0,0 +1,106 @@
`default_nettype none
`timescale 1ns/1ps
module bus_tb;
// https://www.youtube.com/watch?v=WCOAr-96bGc
//boilerplate
logic clk;
logic rst;
// uart inputs and outputs
logic rxd;
logic [7:0] uart_rx_axiod;
logic uart_rx_axiov;
logic txd;
logic [7:0] uart_tx_axiid;
logic uart_tx_axiiv;
logic uart_tx_axiir;
// the parameter will all get filled out in manta's big instantiator thing hehehee
parameter ADDR_WIDTH = 0; // $clog2( how much memory we need rounded up to the nearest 8 )
parameter DATA_WIDTH = 0;
// request bus, gets connected to uart_rx (through a FSM)
logic [ADDR_WIDTH-1:0] req_addr;
logic [DATA_WIDTH-1:0] req_data;
logic req_rw;
logic req_valid;
logic req_ready;
// response bus, get connected to uart_tx (through a FSM, but the data's there in spirit)
logic res_valid;
logic res_ready;
logic res_data;
uart_rx #(
.DATA_WDITH(8),
.CLK_FREQ_HZ(100_000_000),
.BAUDRATE(115200))
uart_rx_uut (
.clk(clk),
.rst(rst),
.rxd(rxd),
.axiod(uart_rx_axiod),
.axiov(uart_rx_axiov));
uart_tx #(
.DATA_WDITH(8),
.CLK_FREQ_HZ(100_000_000),
.BAUDRATE(115200))
uart_tx_uut (
.clk(clk),
.rst(rst),
.txd(txd),
.axiid(uart_tx_axiid),
.axiiv(uart_tx_axiiv),
.axiir(uart_tx_axiir));
bridge_rx bridge_rx_uut(
.clk(clk),
.rst(rst),
// connect to uart_rx
.axiid(uart_rx_axiod),
.axiiv(uart_rx_axiov),
.req_addr(req_addr),
.req_data(req_data),
.req_rw(req_rw),
.req_valid(req_valid),
.req_ready(req_ready));
bridge_tx bridge_tx_uut(
.clk(clk),
.rst(rst),
// connect to uart_tx
.axiod(uart_tx_axiid),
.axiov(uart_tx_axiiv),
.axior(uart_tx_axiir),
.res_valid(res_valid),
.res_ready(res_ready),
.res_data(res_data));
always begin
#5;
clk = !clk;
end
initial begin
$dumpfile("bus.vcd");
$dumpvars(0, bus_tb);
end
endmodule
`default_nettype wire