235 lines
7.6 KiB
Systemverilog
235 lines
7.6 KiB
Systemverilog
|
|
`timescale 1ns/1ps
|
||
|
|
|
||
|
|
module
|
||
|
|
`CASE_NAME();
|
||
|
|
`include "../instantiate_top.sv"
|
||
|
|
|
||
|
|
final mti_fli::mti_Cmd("do ../saveucdb.tcl");
|
||
|
|
|
||
|
|
initial begin
|
||
|
|
$fsdbDumpfile("fsdb_wave.fsdb");
|
||
|
|
$fsdbDumpvars;
|
||
|
|
end
|
||
|
|
|
||
|
|
/*>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>simulation time control>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>*/
|
||
|
|
/*to end the simulation commandary*/
|
||
|
|
/*if you want to end the simulation case by case,just comment the line
|
||
|
|
/*<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<simulation time control<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<*/
|
||
|
|
//TODO:
|
||
|
|
|
||
|
|
logic apb_uart_irq;
|
||
|
|
logic apb_uart_rda; // rx data avaiable
|
||
|
|
logic apb_uart_tde; // tx data empty
|
||
|
|
|
||
|
|
logic apb_uart_req;
|
||
|
|
logic apb_uart_write;
|
||
|
|
logic [16-1:0] apb_uart_addr;
|
||
|
|
logic [32-1:0] apb_uart_wdata;
|
||
|
|
logic [32-1:0] apb_uart_rdata;
|
||
|
|
logic apb_uart_ready;
|
||
|
|
|
||
|
|
logic [16-1:0] apb_uart_paddr;
|
||
|
|
logic apb_uart_psel;
|
||
|
|
logic apb_uart_penable;
|
||
|
|
logic apb_uart_pwrite;
|
||
|
|
logic [32-1:0] apb_uart_pwdata;
|
||
|
|
|
||
|
|
logic [32-1:0] apb_uart_prdata;
|
||
|
|
logic apb_uart_pready;
|
||
|
|
|
||
|
|
// instance vip
|
||
|
|
vip_clock # (.FREQUENCY_MHZ(50)) u0_clock(.duty_percent(50), .jitter_percent(0), .clk(clk));
|
||
|
|
|
||
|
|
apb_uart_top tb_apb_uart_top(
|
||
|
|
.CLK (clk),
|
||
|
|
.RSTN (rstn),
|
||
|
|
/* verilator lint_off UNUSED */
|
||
|
|
.PADDR (apb_uart_paddr),
|
||
|
|
/* lint_on */
|
||
|
|
.PWDATA (apb_uart_pwdata),
|
||
|
|
.PWRITE (apb_uart_pwrite),
|
||
|
|
.PSEL (apb_uart_psel),
|
||
|
|
.PENABLE (apb_uart_penable),
|
||
|
|
.PRDATA (apb_uart_prdata),
|
||
|
|
.PREADY (apb_uart_pready),
|
||
|
|
.PSLVERR (),
|
||
|
|
|
||
|
|
.rx_i (uart_tx), // Receiver input
|
||
|
|
.tx_o (uart_rx), // Transmitter output
|
||
|
|
|
||
|
|
.rda_o (apb_uart_rda), // rx data avaiable
|
||
|
|
.tde_o (apb_uart_tde), // tx data empty
|
||
|
|
.event_o (apb_uart_irq) // interrupt/event output
|
||
|
|
);
|
||
|
|
|
||
|
|
apbmif tb_apb_uart_apbmif(
|
||
|
|
.req (apb_uart_req),
|
||
|
|
.write (apb_uart_write),
|
||
|
|
.addr (apb_uart_addr),
|
||
|
|
.wdata (apb_uart_wdata),
|
||
|
|
.rdata (apb_uart_rdata),
|
||
|
|
.ready (apb_uart_ready),
|
||
|
|
// APB interface
|
||
|
|
.PRESETn (rstn),
|
||
|
|
.PCLK (clk),
|
||
|
|
// APB master
|
||
|
|
.PADDR (apb_uart_paddr),
|
||
|
|
.PSEL (apb_uart_psel),
|
||
|
|
.PENABLE (apb_uart_penable),
|
||
|
|
.PWRITE (apb_uart_pwrite),
|
||
|
|
.PSTRB (),
|
||
|
|
.PWDATA (apb_uart_pwdata),
|
||
|
|
|
||
|
|
.PRDATA (apb_uart_prdata),
|
||
|
|
.PREADY (apb_uart_pready)
|
||
|
|
);
|
||
|
|
|
||
|
|
logic [4:0] ehex;
|
||
|
|
logic ehex_valid;
|
||
|
|
|
||
|
|
logic cli_poll;
|
||
|
|
logic echo_push;
|
||
|
|
|
||
|
|
logic run_priority ;
|
||
|
|
logic cli_poll_pending ;
|
||
|
|
logic echo_push_pending;
|
||
|
|
|
||
|
|
logic apb_uart_ready_d1;
|
||
|
|
logic apb_uart_read_done;
|
||
|
|
logic apb_uart_write_done;
|
||
|
|
logic apb_uart_is_reading;
|
||
|
|
|
||
|
|
always_ff @(posedge clk or negedge rstn) begin
|
||
|
|
if (!rstn) begin
|
||
|
|
apb_uart_ready_d1 <= 1'b1;
|
||
|
|
end else begin
|
||
|
|
apb_uart_ready_d1 <= apb_uart_ready;
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
assign apb_uart_read_done = apb_uart_is_reading && apb_uart_ready && !apb_uart_ready_d1;
|
||
|
|
assign apb_uart_write_done = !apb_uart_is_reading && apb_uart_ready && !apb_uart_ready_d1;
|
||
|
|
|
||
|
|
always_ff @(posedge clk or negedge rstn) begin
|
||
|
|
if (!rstn) begin
|
||
|
|
apb_uart_req <= 0;
|
||
|
|
apb_uart_write <= 0;
|
||
|
|
apb_uart_addr <= 0;
|
||
|
|
run_priority <= 0; // 0: read; 1: write;
|
||
|
|
cli_poll_pending <= 0;
|
||
|
|
echo_push_pending <= 0;
|
||
|
|
apb_uart_is_reading <= 0;
|
||
|
|
end else begin
|
||
|
|
if (cli_poll)
|
||
|
|
cli_poll_pending <= 1'b1;
|
||
|
|
if (echo_push)
|
||
|
|
echo_push_pending <= 1'b1;
|
||
|
|
|
||
|
|
apb_uart_req <= 0;
|
||
|
|
apb_uart_write <= 0;
|
||
|
|
|
||
|
|
if (apb_uart_ready) begin
|
||
|
|
if (cli_poll_pending && !echo_push_pending) begin // read
|
||
|
|
cli_poll_pending <= 1'b0;
|
||
|
|
run_priority <= 1'b1; // next time write first
|
||
|
|
apb_uart_req <= 1'b1;
|
||
|
|
apb_uart_write <= 1'b0;
|
||
|
|
apb_uart_addr <= 0;
|
||
|
|
apb_uart_is_reading <= 1'b1;
|
||
|
|
end else if (!cli_poll_pending && echo_push_pending) begin // write
|
||
|
|
echo_push_pending <= 1'b0;
|
||
|
|
run_priority <= 1'b0; // next time read first
|
||
|
|
apb_uart_req <= 1'b1;
|
||
|
|
apb_uart_write <= 1'b1;
|
||
|
|
apb_uart_addr <= 0;
|
||
|
|
apb_uart_is_reading <= 0;
|
||
|
|
end else if (cli_poll_pending && echo_push_pending) begin
|
||
|
|
if (run_priority) begin // write
|
||
|
|
echo_push_pending <= 1'b0;
|
||
|
|
run_priority <= 1'b0; // next time read first
|
||
|
|
apb_uart_req <= 1'b1;
|
||
|
|
apb_uart_write <= 1'b1;
|
||
|
|
apb_uart_addr <= 0;
|
||
|
|
apb_uart_is_reading <= 0;
|
||
|
|
end else begin // read
|
||
|
|
cli_poll_pending <= 1'b0;
|
||
|
|
run_priority <= 1'b1; // next time write first
|
||
|
|
apb_uart_req <= 1'b1;
|
||
|
|
apb_uart_write <= 1'b0;
|
||
|
|
apb_uart_addr <= 0;
|
||
|
|
apb_uart_is_reading <= 1'b1;
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
initial begin
|
||
|
|
rstn = 0;
|
||
|
|
#1us rstn = 1;
|
||
|
|
end
|
||
|
|
|
||
|
|
initial begin
|
||
|
|
int uart_recv = $fopen("uart_recv.log");
|
||
|
|
cli_poll = 0;
|
||
|
|
#1ns;
|
||
|
|
@(posedge rstn);
|
||
|
|
forever begin
|
||
|
|
wait (apb_uart_rda == 1'b1);
|
||
|
|
@(posedge clk);
|
||
|
|
fork
|
||
|
|
cli_poll = 1'b1;
|
||
|
|
@(posedge clk) cli_poll = 1'b0;
|
||
|
|
join_none
|
||
|
|
@(posedge apb_uart_read_done) $fwrite(uart_recv, "%s", apb_uart_rdata[7:0]);
|
||
|
|
@(negedge apb_uart_rda);
|
||
|
|
end
|
||
|
|
end
|
||
|
|
|
||
|
|
task send_cmd(input string cmd);
|
||
|
|
begin
|
||
|
|
foreach(cmd[i]) begin
|
||
|
|
wait (apb_uart_tde == 1'b1);
|
||
|
|
@(posedge clk);
|
||
|
|
echo_push = 1'b1;
|
||
|
|
apb_uart_wdata = cmd[i];
|
||
|
|
@(posedge clk) echo_push = 1'b0;
|
||
|
|
@(negedge apb_uart_tde);
|
||
|
|
end
|
||
|
|
end
|
||
|
|
endtask
|
||
|
|
|
||
|
|
initial begin
|
||
|
|
echo_push = 0;
|
||
|
|
#1ns;
|
||
|
|
@(posedge rstn);
|
||
|
|
#1ms;
|
||
|
|
send_cmd("\x03");
|
||
|
|
#5ms;
|
||
|
|
send_cmd("\x03");
|
||
|
|
#5ms;
|
||
|
|
send_cmd("\n");
|
||
|
|
#1ms;
|
||
|
|
send_cmd("w");
|
||
|
|
#1ms;
|
||
|
|
send_cmd("\n");
|
||
|
|
send_cmd("w 0 beef1111 beef2222 beef3333 beef4444\n");
|
||
|
|
send_cmd("w 10 beef5555 beef6666 beef7777 beef8888\n");
|
||
|
|
send_cmd("r 0 -s 8 -t a\n");
|
||
|
|
#25ms;
|
||
|
|
send_cmd("\x03");
|
||
|
|
#5ms;
|
||
|
|
send_cmd("\x03");
|
||
|
|
#5ms;
|
||
|
|
send_cmd("\x03");
|
||
|
|
#5ms;
|
||
|
|
send_cmd("r 0 -s 2\n");
|
||
|
|
#5ms;
|
||
|
|
send_cmd("r 8 -s 2\n");
|
||
|
|
#5ms;
|
||
|
|
send_cmd("r 10 -s\n");
|
||
|
|
#5ms;
|
||
|
|
send_cmd("r 10 -s -s\n");
|
||
|
|
end
|
||
|
|
|
||
|
|
endmodule
|