📄 top_tb.v
字号:
ebiReadDat(UCSRA, rRsl);
$display("UCSRA = 0x%H", rRsl);
ebiReadDat(UCSRB, rRsl);
$display("UCSRB = 0x%H", rRsl);
ebiReadDat(UCSRC, rRsl);
$display("UCSRC = 0x%H", rRsl);
ebiReadDat(UDR, rRsl);
if (rRsl == rTstDat) begin
$display("receive data ok!, UDR = 0x%H", rRsl, $time);
end else begin
$display("faile to receive data!", $time);
end
$display("==============");
$stop;
/* 发送0x51, 7bits, 1 stopbit, odd parity */
rTstDat = 8'h51;
rTstCharSize = CSZ_7BITS;
rTstStopBit = SBS_1BIT;
rTstParity = ODD_PARITY;
$display("Frame format is: CharSize=[%d], StopBit=[%d], ParityMode=[%d]", rTstCharSize, rTstStopBit, rTstParity);
ebiWriteDat(UCSRC,
(1 << UPM1) |
(1 << UPM0) |
(1 << UCSZ1) |
(0 << UCSZ0)
);
rTstDat = rTstDat & ((1<<rTstCharSize) - 1);
$display("start send data: 0x%H", rTstDat, $time);
txdGenerate(8'h51, rTstCharSize, rTstParity, rTstStopBit);
if (uart_int) begin
@(negedge uart_int); // wait for rxd completed
$display("Error: failed to receive one frame!");
end else begin
$display("Info: success to receive one frame!");
end
ebiReadDat(UCSRA, rRsl);
$display("UCSRA = 0x%H", rRsl);
ebiReadDat(UCSRB, rRsl);
$display("UCSRB = 0x%H", rRsl);
ebiReadDat(UCSRC, rRsl);
$display("UCSRC = 0x%H", rRsl);
ebiReadDat(UDR, rRsl);
if (rRsl == rTstDat) begin
$display("receive data ok!, UDR = 0x%H", rRsl, $time);
end else begin
$display("faile to receive data!", $time);
end
$display("==============");
$stop;
/* 发送0x51, 8bits, 1 stopbit, no parity */
rTstDat = 8'h51;
rTstCharSize = CSZ_8BITS;
rTstStopBit = SBS_1BIT;
rTstParity = NO_PARITY;
$display("Frame format is: CharSize=[%d], StopBit=[%d], ParityMode=[%d]", rTstCharSize, rTstStopBit, rTstParity);
ebiWriteDat(UCSRC,
(0 << UPM1) |
(0 << UPM0) |
(1 << UCSZ1) |
(1 << UCSZ0)
);
rTstDat = rTstDat & ((1<<rTstCharSize) - 1);
$display("start send data: 0x%H", rTstDat, $time);
txdGenerate(8'h51, rTstCharSize, rTstParity, rTstStopBit);
if (uart_int) begin
@(negedge uart_int); // wait for rxd completed
$display("Error: failed to receive one frame!");
end else begin
$display("Info: success to receive one frame!");
end
ebiReadDat(UCSRA, rRsl);
$display("UCSRA = 0x%H", rRsl);
ebiReadDat(UCSRB, rRsl);
$display("UCSRB = 0x%H", rRsl);
ebiReadDat(UCSRC, rRsl);
$display("UCSRC = 0x%H", rRsl);
ebiReadDat(UDR, rRsl);
if (rRsl == rTstDat) begin
$display("receive data ok!, UDR = 0x%H", rRsl, $time);
end else begin
$display("faile to receive data!", $time);
end
$display("==============");
$stop;
/* 发送0x51, 8bits, 1 stopbit, even parity */
rTstDat = 8'h51;
rTstCharSize = CSZ_8BITS;
rTstStopBit = SBS_1BIT;
rTstParity = EVEN_PARITY;
$display("Frame format is: CharSize=[%d], StopBit=[%d], ParityMode=[%d]", rTstCharSize, rTstStopBit, rTstParity);
ebiWriteDat(UCSRC,
(1 << UPM1) |
(0 << UPM0) |
(1 << UCSZ1) |
(1 << UCSZ0)
);
rTstDat = rTstDat & ((1<<rTstCharSize) - 1);
$display("start send data: 0x%H", rTstDat, $time);
txdGenerate(8'h51, rTstCharSize, rTstParity, rTstStopBit);
if (uart_int) begin
@(negedge uart_int); // wait for rxd completed
$display("Error: failed to receive one frame!");
end else begin
$display("Info: success to receive one frame!");
end
ebiReadDat(UCSRA, rRsl);
$display("UCSRA = 0x%H", rRsl);
ebiReadDat(UCSRB, rRsl);
$display("UCSRB = 0x%H", rRsl);
ebiReadDat(UCSRC, rRsl);
$display("UCSRC = 0x%H", rRsl);
ebiReadDat(UDR, rRsl);
if (rRsl == rTstDat) begin
$display("receive data ok!, UDR = 0x%H", rRsl, $time);
end else begin
$display("faile to receive data!", $time);
end
$display("==============");
$stop;
/* 发送0x51, 8bits, 1 stopbit, odd parity */
rTstDat = 8'h51;
rTstCharSize = CSZ_8BITS;
rTstStopBit = SBS_1BIT;
rTstParity = ODD_PARITY;
$display("Frame format is: CharSize=[%d], StopBit=[%d], ParityMode=[%d]", rTstCharSize, rTstStopBit, rTstParity);
ebiWriteDat(UCSRC,
(1 << UPM1) |
(1 << UPM0) |
(1 << UCSZ1) |
(1 << UCSZ0)
);
rTstDat = rTstDat & ((1<<rTstCharSize) - 1);
$display("start send data: 0x%H", rTstDat, $time);
txdGenerate(8'h51, rTstCharSize, rTstParity, rTstStopBit);
if (uart_int) begin
@(negedge uart_int); // wait for rxd completed
$display("Error: failed to receive one frame!");
end else begin
$display("Info: success to receive one frame!");
end
ebiReadDat(UCSRA, rRsl);
$display("UCSRA = 0x%H", rRsl);
ebiReadDat(UCSRB, rRsl);
$display("UCSRB = 0x%H", rRsl);
ebiReadDat(UCSRC, rRsl);
$display("UCSRC = 0x%H", rRsl);
ebiReadDat(UDR, rRsl);
if (rRsl == rTstDat) begin
$display("receive data ok!, UDR = 0x%H", rRsl, $time);
end else begin
$display("faile to receive data!", $time);
end
$display("==============");
$stop;
#1000;
$display("******************** End Of Test **********************");
$stop;
$finish;
end
assign wAD = (rd_n)? rAD : 8'hzz;
top U_uart_tb(
.clk (clk),
.rst_n (rst_n),
.ad (wAD),
.addr (addr),
.wr_n (wr_n),
.rd_n (rd_n),
.ale (ale),
.txd (txd),
.rxd (rxd),
.int_o (uart_int),
.uart_clk (uart_clk)
);
/*
* 产生系统时钟
*/
always #(CLK / 2) clk <= ~clk;
/*
* 初始化UART的寄存器
*/
task uartInit;
reg [7:0] rTmp;
begin
ebiReadDat(UVER, rTmp);
if (rTmp != 100) begin
$display("the version not equel to 100 but is %d", rTmp);
$stop;
end
else begin
$display("the fpga uart verision is %d", rTmp);
end
ebiWriteDat(UBRRL, 8'h05);
ebiWriteDat(UBRRH, 8'h00);
ebiWriteDat(UCSRC,
(8'h01 << UCSZ1) | // 帧数据位为8位
(8'h01 << UCSZ0) |
(8'h01 << UPM1)
);
ebiWriteDat(UCSRB,
(8'h01 << RXCIE) |
(8'h01 << RXEN) |
(8'h01 << TXEN)
);
end
endtask
/*
* 以查询的方式(Poll Style)检查UART总线上是否接收到数据,
*/
task uartGetChar;
reg [7:0] rTmp;
begin
rTmp = 8'h0;
while ( (rTmp & (1<<RXC)) == 0 ) begin // 等待接收器接收到数据
#100;
ebiReadDat(UCSRA, rTmp);
end
$display("\n==========Get One Char===========");
ebiReadDat(UCSRA, rTmp);
$write("UCSRA = 0x%H", rTmp);
if (rTmp & (1<<FE))
$write("detect frame error!");
if (rTmp & (1<<DOR))
$write("detect OverRun Error!");
if (rTmp & (1<<UPE))
$write("detect Parity Check Error!");
$write("\n");
ebiReadDat(UCSRB, rTmp);
$display("UCSRB = 0x%H", rTmp);
ebiReadDat(UCSRC, rTmp);
$display("UCSRC = 0x%H", rTmp);
ebiReadDat(UDR, rTmp);
$display("UDR = 0x%H", rTmp);
$display("has get one char: 0x%H at %dns", rTmp, $realtime);
ebiWriteDat(UCSRA, 1<<TXC);
$display("clear xmint done flag!");
ebiReadDat(UCSRA, rTmp);
$display("UCSRA = 0x%H", rTmp);
$display("============End Of Get Char===========");
end
endtask
/*
* 根据设定的地址, 读取EBI的数据, 模拟C51外部总线的时序, 低8位的地址和数据线
* 复用, 使用ALE外Address Lock Enable
*/
task ebiReadDat;
input [15:0] a;
output [7:0] return;
reg [7:0] return;
begin
@(negedge clk)
ale = 1'b1;
@(posedge clk)
rAD = a[7:0];
addr = a[15:8];
@(negedge clk)
ale = 1'b0;
@(posedge clk)
rd_n = #1 1'b0;
@(posedge clk)
return = wAD;
rd_n = #1 1'b1;
end
endtask
/*
* 往EBI(Extenl Bus Interface)写数据, 模拟C51的外部总线的时序, 输入为地址和数
* 据
*/
task ebiWriteDat;
input [15:0] addr_i;
input [7:0] data_i;
begin
@(negedge clk)
ale = 1'b1;
@(posedge clk)
rAD = addr_i[7:0];
addr = addr_i[15:8];
@(negedge clk)
ale = 1'b0;
@(posedge clk)
rAD = data_i;
wr_n = #1 1'b0;
@(posedge clk)
wr_n = #1 1'b1;
end
endtask
/*
* 产生TXD的信号, 根据设定的UART帧格式, 产生个UART的发送器序列
*/
initial rBaudRate = 0;
task txdGenerate;
input [7:0] data_i;
input [3:0] char_size_i;
input [1:0] parity;
input stop_bit;
integer i;
reg rParVal;
begin
ebiWriteDat(UDR, data_i); // 利用UART的发送器产生, 作比较
rParVal = 1'b0;
/* 发生起始位 */
@(posedge clk)
rxd = 1'b0;
rBaudRate = ~rBaudRate;
dlyBaud;
/* 移位产生数据位 */
for (i=0; i<char_size_i; i = i+1) begin
rxd = data_i[i];
rParVal = rParVal ^ rxd;
rBaudRate = ~rBaudRate;
dlyBaud;
end
/* 产生奇偶校验位 */
if (parity == 2'h2) begin
rxd = rParVal;
rBaudRate = ~rBaudRate;
dlyBaud;
end
else if (parity == 2'h3) begin
rxd = ~rParVal;
rBaudRate = ~rBaudRate;
dlyBaud;
end
rxd = 1'b1;
rBaudRate = ~rBaudRate;
dlyBaud;
if (stop_bit) begin
rxd = 1'b1;
rBaudRate = ~rBaudRate;
dlyBaud;
end
rBaudRate = ~rBaudRate;
end
endtask
/*
* 延时1个波特的时间, 用于产生模拟的UART总线
*/
task dlyBaud;
#(16 * DIVIDER_FACTOR * CLK);
endtask
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -