我用verilog 写了UART Tx 的代码。
到目前为止,我先想测试UART传输,但我不太确定如何测试它。
我应该测试什么呢?
我不是要求测试代码。 我需要一些有关测试UART软核的指导。
谢谢!
- module Tx_top(clk, reset, start, i_data, serial_out) // UART transmitter : parallel input, serial output
- input clk; // 48MHz
- input reset;
- input start; // i_data is valid, so start transmission
- input[7:0] i_data;
- output serial_out;
- wire baud_out; // 9600bps baudrate clock
- wire serial_data; // output from serializer (TxUART)
- TxUART tx (.clk(baud_out), .reset(reset), .start_tx(start), .i_data(i_data), .o_data(serial_data));
- baud_generator bg (.clk(clk), .baud_out(baud_out));
- shift_register sreg (.clk(baud_out), .reset(reset), .data_in(serial_data), .data_out(serial_out));
- // FIFO tx_fifo (clk, reset, enqueue, dequeue, flush, i_value, almost_full, almost_empty, o_value);
- endmodule
复制代码- `define Tx_IDLE_BIT 0
- `define Tx_START_BIT 1
- `define Tx_DATA_BITS < `Tx_PARITY_BIT
- `define Tx_PARITY_BIT 10
- `define Tx_STOP_BIT 11
- module TxUART(clk, reset, start_tx, i_data, o_data)
- input clk, reset, start_tx;
- input[7:0] i_data;
- output reg o_data;
- reg[3:0] state, next_state;
- wire parity_bit;
- always @(posedge clk)
- begin
- if (reset)
- state <= `Tx_IDLE_BIT;
- else
- state <= next_state;
- end
- always @(*)
- begin : tx_fsm
- case(state)
- `Tx_IDLE_BIT : next_state = (start_tx == 1) ? Tx_START_BIT : `Tx_IDLE_BIT;
- o_data = 1;
- `Tx_START_BIT : next_state = `Tx_DATA_BITS;
- o_data = 0;
- `Tx_DATA_BITS : next_state = state + 1;
- o_data = i_data[state-2];
- `Tx_PARITY_BIT : next_state = `Tx_STOP_BIT;
- o_data = parity_bit;
- `Tx_STOP_BIT : next_state = `Tx_IDLE_BIT;
- o_data = 1;
- default : next_state = `Tx_IDLE_BIT;
- o_data = 1;
- endcase
- end
- assign parity_bit = ^i_data; // even parity http://www.asic-world.com/examples/verilog/parity.html
- endmodule
复制代码- // credit: Adapted from http://zipcpu.com/blog/2017/06/02/generating-timing.html
- module baud_generator(clk, baud_out) // we are obtaining baud_out = 9600bps = clk/5000 where clk = 48MHz
- input clk;
- output baud_out;
- wire ck_stb;
- reg[15:0] counter = 0;
- always @(posedge clk)
- {ck_stb, counter} <= counter + 13; // (2^16)/5000 = 13.1
- assign baud_out = ck_stb;
- endmodule
复制代码- // Credit: Adapted from http://www.referencedesigner.com/tutorials/verilog/verilog_32.php
- module shift_register(clk, reset, data_in, data_out) // cascade of 10 registers
- parameter N=10;
- input wire clk, reset;
- input wire data_in;
- output wire data_out;
- reg [N-1:0] r_reg;
- wire [N-1:0] r_next;
- always @(posedge clk)
- begin
- if (reset)
- r_reg <= 0;
- else
- r_reg <= r_next;
- end
- assign r_next = {data_in, r_reg[N-1:1]};
- assign data_out = r_reg[0]; // Transmit LSB first
- endmodule
复制代码- // Adapted from https://github.com/jbush001/NyuziProcessor/blob/master/hardware/core/sync_fifo.sv
- module FIFO (clk, reset, enqueue, dequeue, flush, i_value, almost_full, almost_empty, o_value)
- input clk, reset, enqueue, dequeue, flush, i_value;
- output almost_full, almost_empty, o_value;
- parameter SIZE = 22;
- parameter ALMOST_FULL_THRESHOLD = SIZE;
- parameter ALMOST_EMPTY_THRESHOLD = 1);
- reg[4:0] head, tail, count;
- assign almost_full = count >= ALMOST_FULL_THRESHOLD;
- assign almost_empty = count <= ALMOST_EMPTY_THRESHOLD;
- assign o_value = data[head];
- always @(posedge clk)
- begin
- if (reset) begin
- head <= 0;
- tail <= 0;
- count <= 0;
- end
- else begin
- if (flush) begin
- head <= 0;
- tail <= 0;
- count <= 0;
- end
- else begin
- if (enqueue) begin
- tail <= tail + 1;
- data[tail] <= i_value;
- end
- if (dequeue) begin
- head <= head + 1;
- end
- if (enqueue && !dequeue)
- count <= count + 1;
- else if (dequeue && !enqueue)
- count <= count - 1;
- end
- end
- end
- endmodule
复制代码
一周热门 更多>