实验目的
本实验的目的是为了一个开源的UART(以下简称op_uart)模块编写总线功能模型,在测试平台对UART模块进行功能验证,在下一个tinycore验证试验,在tinycore中会包含另一个实现方式不同的UART模块,op_uart模块及其BFM可以在tinycore验证试验中反复使用,与tinycore进行通信。总线功能模型的框图如下:
UART模块介绍
下面将开源UART简称为 op_uart, incore中的UART称为tuat,关于tuar的说明见《UART说明》这篇文档。op_uart简述如下:
1、支持发送和接收数据能力。
2、支持8-N-1和8-N-2的数据传输格式:即8位数据位、没有奇偶校验位、1位起始位、1位或者2位停止位。
3、每接收到个新的数据,便会断言iq中断信号;每发送个新的数据,便会断言iq中断信号;持续时间一个周期。
opua寄存器列表如下:
op_uart参数列表:
op_uart 信号列表:
写时序:
从以上介绍可以看出,虽然op_uart和ti_uart是两个不同的UART模块,使用它们的方法是差不多的,都是通过 对UART模块内部寄存器进行读写,从而达到控制UART行为的目的
实验代码导读
test case解析
通过一系列的任务调用来构造合适的 test case ———— 调用Set_thru任务来设置op_uart工作方式;调用 Send任务来控制op_uart发送数据;调用Rx_stimulus任务来模拟op_uart的接收数据。可以看出,通过模 块化的封装使得测试平台变得可重用、易使用、结构清晰易维护。
实验要求
将harness.sv文件中的代码补全,使得test case 可以正常运行,并通过观察波形来验证设计的正确性。
试验代码
`include "define.vh"
module harness;
reg sys_clk;
reg sys_rst;
reg [13:0] csr_a;
reg csr_we;
reg [31:0] csr_di;
wire [31:0] csr_do;
wire rx_irq;
wire tx_irq;
reg uart_rx;
wire uart_tx;
//
op_uart #(
.csr_addr (`CSR_ADDR),
.clk_freq ( `CLK_FREQ),
.baud ( `BAUD )
) u_uart (
.sys_clk (sys_clk),
.sys_rst (sys_rst),
.csr_a (csr_a),
.csr_we (csr_we),
.csr_di (csr_di),
.csr_do (csr_do),
.rx_irq (rx_irq),
.tx_irq (tx_irq),
.uart_rx (uart_rx),
.uart_tx (uart_tx)
);
initial begin
sys_clk = 0;
sys_rst = 0;
csr_a = 0;
csr_we = 0;
csr_di = 0;
uart_rx = 1;
end
//clock generator
always
begin
#(`CYCLE/2) sys_clk <= 1'b0;
#(`CYCLE/2) sys_clk <= 1'b1;
end
// sync reset
task Sync_rst;
begin
sys_rst = 1'b0;
wait (sys_clk !== 1'bx);
@(negedge sys_clk);
sys_rst <= 1'b1;
@(negedge sys_clk);
@(negedge sys_clk);
sys_rst <= 1'b0;
end
endtask
//settings
task Set_thru;
input sel;
begin
@(negedge sys_clk);
csr_we = 1;
csr_a = {12'h0,2'b10};
csr_di = {31'b0, sel};
@(negedge sys_clk);
csr_we = 0;
end
endtask
//send data
task Send;
input [7:0] data;
begin
@(negedge sys_clk);
csr_we = 1;
csr_a = {4'h0,8'b0,2'b00};
csr_di = {24'b0,data};
@(negedge sys_clk);
csr_we = 0;
//补充代码,对op_uart施加符合op_uart接口时序协议的激励,使得op_uart的输出端口uart_tx发送出正确数据。
end
endtask
//rx stimulus//接受的激励
task Rx_stimulus;
input [7:0] data;
begin
//补充代码,模拟op_uart的输入端口uart_rx的时序行为,使得op_uart从uart_rx中解析出正确的数据。
end
endtask
endmodule