`timescale 1ns/1ps
module mem_uart_tb;
// CLK = 12MHz
parameter CLK_PERIOD = 83;
// BAUD = 9600
parameter SAMPLE = 1250; // SAMPLE = CLK_HZ / BAUDRATE
parameter SAMPLE_TB = 104167; // SAMPLE_TB = 1e9 / BAUDRATE
parameter DATA_WIDTH = 16,
ADDR_WIDTH = 64;
reg i_clk;
reg i_nrst;
reg [DATA_WIDTH-1:0] i_data;
reg [ADDR_WIDTH-1:0] i_addr;
wire [DATA_WIDTH-1:0] o_data;
reg i_read_valid;
wire o_read_accept;
reg i_write_valid;
wire o_write_accept;
reg i_uart_rx;
wire o_uart_tx;
mem_uart #(
.DATA_WIDTH (DATA_WIDTH ),
.ADDR_WIDTH (ADDR_WIDTH ),
.SAMPLE (SAMPLE )
) mem_uart(
.i_clk (i_clk ),
.i_nrst (i_nrst ),
.i_data (i_data ),
.i_addr (i_addr ),
.o_data (o_data ),
.i_read_valid (i_read_valid ),
.o_read_accept (o_read_accept ),
.i_write_valid (i_write_valid ),
.o_write_accept (o_write_accept ),
.i_uart_rx (i_uart_rx ),
.o_uart_tx (o_uart_tx )
);
initial begin
while(1) begin
#(CLK_PERIOD/2) i_clk = 0;
#(CLK_PERIOD/2) i_clk = 1;
end
end
initial begin
$dumpfile("mem_uart.vcd");
$dumpvars(0,mem_uart_tb);
end
task uart_send;
input [7:0] send;
integer i;
begin
i_uart_rx = 0;
for(i=0;i<8;i=i+1)
#SAMPLE_TB i_uart_rx = send[i];
#SAMPLE_TB i_uart_rx = 1;
end
endtask
task uart_get;
output [7:0] get;
integer i;
begin
while(o_uart_tx == 1)
@(posedge i_clk);
#(SAMPLE_TB*1.5)
get = 0;
for(i=0;i<8;i=i+1) begin
get[i] = o_uart_tx;
#SAMPLE_TB;
end
$display("%tps uart_get = %x",$time,get);
end
endtask
reg [7:0] uart;
initial begin
while(1)
uart_get(uart);
end
initial begin
while(!i_read_valid) @(posedge i_clk);
#99999999 uart_send(8'h77);
uart_send(8'h66);
#9999999
$finish;
end
initial begin
// Initial
i_uart_rx = 1'b1;
i_write_valid = 1'b0;
i_read_valid = 1'b0;
// Reset
i_nrst = 1'b1;
#77 i_nrst = 1'b0;
#77 i_nrst = 1'b1;
// Writes
#7777 i_data = 16'hABCD;
i_addr = 64'h0123456789ABCDEF;
i_write_valid = 1'b1;
while(!o_write_accept) @(posedge i_clk);
i_write_valid = 1'b0;
#7777777 i_data = 16'hBEEF;
i_addr = 64'hDEADDEADDEADDEAD;
i_write_valid = 1'b1;
while(!o_write_accept) @(posedge i_clk);
i_write_valid = 1'b0;
#1 i_data = 16'hABCD;
i_addr = 64'h0123456789ABCDEF;
i_write_valid = 1'b1;
while(!o_write_accept) @(posedge i_clk);
i_write_valid = 1'b0;
// Reads
#77777 i_read_valid = 1'b1;
i_addr = 64'hDEADDEADDEADDEAD;
while(!o_read_accept) @(posedge i_clk);
i_read_valid = 1'b0;
end
endmodule