1.用System Verilog书写7位数据位,1位偶校验,波特率为115200bps的uart串行发送端 2. 用SV书写对应的行为模型(接收端),并输出激励中的字节值,奇偶性错误的,输出校验错误 3.编写testcase
时间: 2024-05-08 17:17:45 浏览: 109
1. 串行发送端代码如下:
```systemverilog
module uart_serial_tx
#(
parameter BAUD_RATE = 115200
)
(
input clk,
input rst,
input [6:0] data_in,
output reg tx_out
);
// Internal counter for baud rate
// 1 start bit + 7 data bits + 1 parity bit + 1 stop bit = 10 bits per byte
localparam BAUD_COUNTER_MAX = ($root.BAUD_RATE / 10) - 1;
reg [15:0] baud_counter = 0;
// Parity calculation
wire parity = ^data_in;
// State machine for transmitting data
typedef enum logic [2:0] {
IDLE,
START,
DATA,
PARITY,
STOP
} state_t;
state_t state = IDLE;
always @(posedge clk) begin
if (rst) begin
baud_counter <= 0;
tx_out <= 1'b1;
state <= IDLE;
end
else begin
// Baud rate generation
baud_counter <= (baud_counter == BAUD_COUNTER_MAX) ? 0 : (baud_counter + 1);
case (state)
IDLE: begin
if (data_in !== 7'b0) begin
state <= START;
end
end
START: begin
tx_out <= 1'b0;
state <= DATA;
end
DATA: begin
tx_out <= data_in[0];
data_in <= {data_in[5:1], parity};
state <= PARITY;
end
PARITY: begin
tx_out <= parity;
state <= STOP;
end
STOP: begin
tx_out <= 1'b1;
state <= IDLE;
end
default: state <= IDLE;
endcase
end
end
endmodule
```
2. 串行接收端代码如下:
```systemverilog
module uart_serial_rx
#(
parameter BAUD_RATE = 115200
)
(
input clk,
input rst,
input rx_in,
output reg [6:0] data_out,
output reg parity_err,
output reg frame_err
);
// Internal counter for baud rate
// 1 start bit + 7 data bits + 1 parity bit + 1 stop bit = 10 bits per byte
localparam BAUD_COUNTER_MAX = ($root.BAUD_RATE / 10) - 1;
reg [15:0] baud_counter = 0;
// State machine for receiving data
typedef enum logic [2:0] {
IDLE,
START,
DATA,
PARITY,
STOP
} state_t;
state_t state = IDLE;
always @(posedge clk) begin
if (rst) begin
baud_counter <= 0;
data_out <= 7'b0;
parity_err <= 1'b0;
frame_err <= 1'b0;
state <= IDLE;
end
else begin
// Baud rate generation
baud_counter <= (baud_counter == BAUD_COUNTER_MAX) ? 0 : (baud_counter + 1);
case (state)
IDLE: begin
if (!rx_in) begin
state <= START;
end
end
START: begin
state <= DATA;
end
DATA: begin
data_out <= {data_out[5:0], rx_in};
state <= PARITY;
end
PARITY: begin
if (rx_in !== ^data_out) begin
parity_err <= 1'b1;
end
state <= STOP;
end
STOP: begin
if (rx_in) begin
frame_err <= 1'b1;
end
state <= IDLE;
end
default: state <= IDLE;
endcase
end
end
endmodule
```
3. 编写testcase如下:
```systemverilog
module test_uart_serial;
// Parameters
localparam BAUD_RATE = 115200;
// DUT
uart_serial_tx dut_tx (
.clk(clk),
.rst(rst),
.data_in(data_in),
.tx_out(tx_out)
);
uart_serial_rx dut_rx (
.clk(clk),
.rst(rst),
.rx_in(rx_in),
.data_out(data_out),
.parity_err(parity_err),
.frame_err(frame_err)
);
// Clock
logic clk = 0;
always #((1e9 / BAUD_RATE) / 2) clk = ~clk;
// Reset
logic rst = 0;
always #((1e9 / BAUD_RATE) * 10) rst = 1'b1;
// Testcase
initial begin
// Even parity
data_in = 7'b1010101;
#1000;
assert (tx_out === 1'b1) else $error("tx_out should be high");
assert (data_out === 7'b1010101) else $error("data_out should be 7'b1010101");
assert (!parity_err) else $error("parity_err should be low");
assert (!frame_err) else $error("frame_err should be low");
// Odd parity
data_in = 7'b1010111;
#1000;
assert (tx_out === 1'b1) else $error("tx_out should be high");
assert (data_out === 7'b1010111) else $error("data_out should be 7'b1010111");
assert (!parity_err) else $error("parity_err should be low");
assert (!frame_err) else $error("frame_err should be low");
// Parity error
data_in = 7'b1010110;
#1000;
assert (tx_out === 1'b1) else $error("tx_out should be high");
assert (data_out === 7'b1010110) else $error("data_out should be 7'b1010110");
assert (parity_err) else $error("parity_err should be high");
assert (!frame_err) else $error("frame_err should be low");
// Frame error
data_in = 7'b1010101;
#1000;
assert (tx_out === 1'b1) else $error("tx_out should be high");
assert (data_out === 7'b0) else $error("data_out should be 7'b0");
assert (!parity_err) else $error("parity_err should be low");
assert (frame_err) else $error("frame_err should be high");
end
endmodule
```
阅读全文