add in bus architecture prototypes from the last few days
This commit is contained in:
parent
f3710d4cbc
commit
e55d919098
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
Loading…
Reference in New Issue