?? h16550tb4.v
字號:
//////////////////////////////////////////////////////////////////////////////////////////////////----------------------------------------------------------------------//// Copyright (c) 2002-2003 CAST, inc.//// Please review the terms of the license agreement before using this// file. If you are not an authorized user, please destroy this source// code file and notify CAST immediately that you inadvertently received// an unauthorized copy.//----------------------------------------------------------------------//// Project : H16550 UART//// File : h16550tb4.vhd//// Dependencies : h16550w.vhd//// Model Type : Simulation Model (Testbench)//// Description : H16550 testbench 4//// Designer : JV//// QA Engineer : Joram Heilbronner//// Creation Date : 13-January-2002//// Last Update : 15-February-2002//// Version : 2.0V//// History : 1.1 - 02/18/02 VHDL Release//// Tested Operations: REGISTERS; write and READ // TRANSMISSION; different modes can be changed by modify initial constant \"initLCR\"// RECEIVING// outputS DTR, RTS, OUT1 and OUT2// INPUTS CTS, DSR, DCD and SIN; and effects to Modem Status Register// INTERRUPTS// BAUDOUT; values of the Divisor registers can be changed//// The main idea of testbench is to write values to registers and check interrupts,// status ot the UART and outputs several times// // The UART is tested in several combinations// Different values of data and stop bits and parity operations are tested// All cases are descripted in next table// // CASE 1: 7 data bits, no parity, 1 stop bit => LCReg = \"00110010\"// CASE 2: 7 data bits, stick parity '1', 2 stop bits => LCReg = \"00101110\"// CASE 3: 7 data bits, stick parity '0', 1 stop bit => LCReg = \"00111010\"// CASE 4: 7 data bits, even parity, 2 stop bits => LCReg = \"00011110\"// CASE 5: 5 data bits, no parity, 1.5 stop bits => LCReg = \"00010100\"// CASE 6: 5 data bits, stick parity '1', 1 stop bit => LCReg = \"00101000\"// CASE 7: 5 data bits, stick parity '0', 1 stop bit => LCReg = \"00111000\"// CASE 8: 5 data bits, odd parity, 1.5 stop bits => LCReg = \"00001100\"// CASE 9: 6 data bits, no parity, 1 stop bit => LCReg = \"00100001\"// CASE 10: 6 data bits, stick parity '1', 2 stop bits => LCReg = \"00101101\"// CASE 11: 6 data bits, stick parity '0', 2 stop bits => LCReg = \"00111101\"// CASE 12: 6 data bits, even parity, 1 stop bit => LCReg = \"00011001\"// CASE 13: 8 data bits, no parity, 1 stop bit => LCReg = \"00000011\"// CASE 14: 8 data bits, stick parity '1', 1 stop bit => LCReg = \"00101011\"// CASE 15: 8 data bits, stick parity '0', 2 stop bits => LCReg = \"00111111\"// CASE 16: 8 data bits, odd parity, 2 stop bits => LCReg = \"00001111\"//// Run for 1100 us//----------------------------------------------------------------------`timescale 1 ns/1 psmodule h16550tb (); parameter scale = 1.0; reg test_done; integer errors; reg mr; reg[2:0] a; reg ads; reg cs; reg wr; reg rd; reg clk; reg rclk; reg sin; reg cts; reg dsr; reg dcd; reg ri; wire ddis; wire baudout; wire sout; wire rxrdyn; wire txrdyn; wire rts; wire dtr; wire out1; wire out2; wire intr; wire[7:0] dout; reg[7:0] data; reg[7:0] din; parameter period = 100 * scale; parameter cpu_tpd = period / 3; parameter cpu_trdwr = cpu_tpd / 2; reg debug; // Used for regression testing // CONSTANTs to write to registers // The value of the Line Control Register constant can be changed to appropriate operation mode // The values of the Divisor registers can be changed to modify data speed reg[7:0] initlcr; parameter[7:0] initmcr = 8'b00000101; parameter[7:0] initier = 8'b00001111; parameter[7:0] initsr = 8'b11011111; parameter[7:0] initdlr = 8'b00000010; parameter[7:0] initdmr = 8'b00000000; reg[7:0] initthr; // ADDRESSES of the registers // THESE values can not be changed parameter[2:0] rbradd = 3'b000; parameter[2:0] thradd = 3'b000; parameter[2:0] dlradd = 3'b000; parameter[2:0] dmradd = 3'b001; parameter[2:0] ieradd = 3'b001; parameter[2:0] iiradd = 3'b010; parameter[2:0] lcradd = 3'b011; parameter[2:0] mcradd = 3'b100; parameter[2:0] lsradd = 3'b101; parameter[2:0] msradd = 3'b110; parameter[2:0] sradd = 3'b111; reg gnd; reg vcc; reg do_reset; task wait_n_cycle; input ncycle; integer ncycle; begin begin : xhdl_8 integer i; for(i = ncycle; i >= 0; i = i - 1) begin @(posedge clk); end end end endtask task cpu_write; input[7:0] data; input[2:0] reg_addr; input dlab; begin @(posedge clk); #cpu_tpd; a <= reg_addr ; cs <= 1'b1 ; din <= data ; #cpu_trdwr; wr <= 1'b1 ; @(posedge clk); #cpu_tpd; wr <= 1'b0 ; #cpu_trdwr; cs <= 1'b0 ; din <= 8'bZZZZZZZZ ; $write($stime,,"ns MPU Write: Register"); case (reg_addr) 3'b000 : begin if (dlab) begin $write(" DLR"); end else begin $write(" THR"); end end 3'b001 : begin if (dlab) begin $write(" DMR"); end else begin $write(" IER"); end end 3'b010 : begin $write(" FCR "); end 3'b011 : begin $write(" LCR "); end 3'b100 : begin $write(" MCR "); end 3'b101 : begin $write(" LSR "); end 3'b110 : begin $write(" MSR "); end 3'b111 : begin $write(" SCR "); end default : begin $write(" Unknown "); end endcase $display("= %b", data); end endtask task cpu_read; input[2:0] reg_addr; input[7:0] ref; input dlab; input check; begin @(posedge clk); #cpu_tpd; a <= reg_addr ; cs <= 1'b1 ; #cpu_trdwr; rd <= 1'b1 ; @(posedge clk); #cpu_tpd; rd <= 1'b0 ; $write($stime,,"ns MPU Read: Register"); case (reg_addr) 3'b000 : begin if (dlab) begin $write(" DLR"); end else begin $write(" RBR"); end end 3'b001 : begin if (dlab) begin $write(" DMR"); end else begin $write(" IER"); end end 3'b010 : begin $write(" ISR "); end 3'b011 : begin $write(" LCR "); end 3'b100 : begin $write(" MCR "); end 3'b101 : begin $write(" LSR "); end 3'b110 : begin $write(" MSR "); end 3'b111 : begin $write(" SCR "); end default : begin $write(" Unknown "); end endcase if (check) begin $write("= %b", dout); end else begin $display("= %b", dout); end if (check) begin if (dout != ref) begin $write(" ##### NOK"); $write(" EXPECTED RESULT IS "); $display(" %b #####", ref); errors <= errors + 1 ; end else begin $display(" OK"); end end #cpu_trdwr; cs <= 1'b0 ; @(posedge clk); #cpu_tpd; end endtask initial begin test_done <= 1'b0; errors <= 0; mr <= 1'b1; a <= 3'b000 ; ads <= 1'b1; cs <= 1'b0; wr <= 1'b0; rd <= 1'b0; clk <= 1'b0; rclk <= 1'b0; sin <= 1'b0; cts <= 1'b1; dsr <= 1'b1; dcd <= 1'b1; ri <= 1'b1; din <= 8'b00000000 ; debug <= 1'b0; initlcr <= 8'b00110010; initthr <= 8'b01010110; gnd <= 1'b0; vcc <= 1'b1; do_reset <= 1'b0; end h16550w u1 (.a(a), .adsn(ads), .cs0(cs), .cs1(vcc), .cs2n(gnd), .wr(wr), .rd(rd), .mr(mr), .clk(clk), .rclk(rclk), .sin(sin), .ctsn(cts), .dsrn(dsr), .dcdn(dcd), .rin(ri), .ddis(ddis), .baudoutn(baudout), .sout(sout), .rtsn(rts), .dtrn(dtr), .out1n(out1), .out2n(out2), .intr(intr), .rxrdyn(rxrdyn), .txrdyn(txrdyn), .dout(dout[7:0]), .din(din[7:0])); //------------------------------------------------- // Infinite clock generator //------------------------------------------------- always @(baudout) begin rclk <= baudout ; end always @(sout) begin sin <= sout ; end //------------------------------------------------- // Asynchronous reset //------------------------------------------------- always begin #50; mr <= 1'b1 ; #230; mr <= 1'b0 ; @(posedge do_reset); mr <= 1'b1 ; #200; mr <= 1'b0 ; forever #100000; end always begin : clk_stim forever begin #(period / 2); clk <= ~clk ; if (test_done) begin clk <= ~clk ; $display("TEST COMPLETE"); if (errors == 0) begin $display("There were no errors");
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -