Files

235 lines
7.6 KiB
Systemverilog
Raw Permalink Normal View History

2026-03-06 16:22:17 +08:00
`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