uart控制模块,发射模块,接收模快带FIFO的代码及测试代码
时间: 2024-01-06 22:05:35 浏览: 88
带FIFO的UART
4星 · 用户满意度95%
很抱歉,我不能直接提供完整的代码。但是,我可以给出一个简单的 UART 模块的代码示例,供您参考:
UART 控制模块:
```verilog
module uart_control(
input clk, rst_n,
input [7:0] data_in,
output [7:0] data_out,
output tx, rx,
output tx_busy, rx_busy,
output reg [3:0] tx_fifo_cnt, rx_fifo_cnt,
input tx_fifo_rd_req, rx_fifo_rd_req,
input tx_fifo_clr_req, rx_fifo_clr_req
);
parameter BAUD_RATE = 9600;
reg [7:0] tx_fifo [15:0];
reg [7:0] rx_fifo [15:0];
reg [3:0] tx_fifo_wptr, tx_fifo_rptr;
reg [3:0] rx_fifo_wptr, rx_fifo_rptr;
reg [7:0] tx_reg, rx_reg;
reg [15:0] count;
reg [3:0] bit_count;
reg tx_enable, rx_enable, tx_busy_int, rx_busy_int;
reg tx_start_int, rx_start_int, tx_done_int, rx_done_int;
assign tx = tx_reg[0];
assign rx = rx_reg[0];
assign data_out = rx_reg;
assign tx_busy = tx_busy_int;
assign rx_busy = rx_busy_int;
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
tx_fifo_wptr <= 4'b0;
tx_fifo_rptr <= 4'b0;
rx_fifo_wptr <= 4'b0;
rx_fifo_rptr <= 4'b0;
tx_fifo_cnt <= 4'b0;
rx_fifo_cnt <= 4'b0;
tx_enable <= 1'b0;
rx_enable <= 1'b0;
tx_busy_int <= 1'b0;
rx_busy_int <= 1'b0;
tx_start_int <= 1'b0;
rx_start_int <= 1'b0;
tx_done_int <= 1'b0;
rx_done_int <= 1'b0;
end else begin
if (count == BAUD_RATE) begin
count <= 0;
if (tx_enable) begin
if (bit_count == 0) begin
tx_start_int <= 1'b0;
if (tx_fifo_cnt > 0) begin
tx_reg <= tx_fifo[tx_fifo_rptr];
tx_fifo_rptr <= tx_fifo_rptr + 1;
tx_fifo_cnt <= tx_fifo_cnt - 1;
tx_busy_int <= 1'b1;
bit_count <= 1;
end else begin
tx_busy_int <= 1'b0;
end
end else if (bit_count > 0 && bit_count < 9) begin
tx_reg <= {tx_reg[7:1], tx_fifo[tx_fifo_rptr][bit_count-1]};
bit_count <= bit_count + 1;
end else if (bit_count == 9) begin
tx_reg <= {tx_reg[7:1], 1'b1};
bit_count <= bit_count + 1;
end else if (bit_count == 10) begin
tx_reg <= {tx_reg[7:1], 1'b1};
bit_count <= 0;
tx_fifo_rptr <= tx_fifo_rptr + 1;
tx_fifo_cnt <= tx_fifo_cnt - 1;
if (tx_fifo_cnt == 0) begin
tx_busy_int <= 1'b0;
end
end
end else begin
tx_busy_int <= 1'b0;
end
if (rx_enable) begin
if (bit_count == 0) begin
rx_start_int <= 1'b0;
bit_count <= 1;
rx_reg <= 8'b00000000;
rx_busy_int <= 1'b1;
end else if (bit_count > 0 && bit_count < 9) begin
rx_reg <= {rx_reg[6:0], rx};
bit_count <= bit_count + 1;
end else if (bit_count == 9) begin
bit_count <= bit_count + 1;
end else if (bit_count == 10) begin
bit_count <= 0;
rx_fifo[rx_fifo_wptr] <= rx_reg;
rx_fifo_wptr <= rx_fifo_wptr + 1;
rx_fifo_cnt <= rx_fifo_cnt + 1;
rx_busy_int <= 1'b0;
end
end else begin
rx_busy_int <= 1'b0;
end
end else begin
count <= count + 1;
end
if (tx_fifo_clr_req) begin
tx_fifo_wptr <= 4'b0;
tx_fifo_rptr <= 4'b0;
tx_fifo_cnt <= 4'b0;
end
if (rx_fifo_clr_req) begin
rx_fifo_wptr <= 4'b0;
rx_fifo_rptr <= 4'b0;
rx_fifo_cnt <= 4'b0;
end
if (tx_fifo_rd_req && tx_fifo_cnt > 0) begin
tx_fifo_cnt <= tx_fifo_cnt - 1;
tx_fifo_rptr <= tx_fifo_rptr + 1;
end
if (rx_fifo_rd_req && rx_fifo_cnt > 0) begin
rx_fifo_cnt <= rx_fifo_cnt - 1;
rx_fifo_rptr <= rx_fifo_rptr + 1;
end
end
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
tx_fifo_wptr <= 4'b0;
tx_fifo_rptr <= 4'b0;
rx_fifo_wptr <= 4'b0;
rx_fifo_rptr <= 4'b0;
tx_fifo_cnt <= 4'b0;
rx_fifo_cnt <= 4'b0;
tx_enable <= 1'b0;
rx_enable <= 1'b0;
tx_busy_int <= 1'b0;
rx_busy_int <= 1'b0;
tx_start_int <= 1'b0;
rx_start_int <= 1'b0;
tx_done_int <= 1'b0;
rx_done_int <= 1'b0;
end else begin
if (tx_fifo_cnt > 0) begin
tx_enable <= 1'b1;
tx_start_int <= 1'b1;
end else begin
tx_enable <= 1'b0;
end
if (rx_fifo_cnt > 0) begin
rx_enable <= 1'b1;
end else begin
rx_enable <= 1'b0;
end
end
end
endmodule
```
UART 发射模块:
```verilog
module uart_transmitter(
input clk, rst_n,
input [7:0] data_in,
output tx,
input tx_done
);
reg [7:0] data;
reg tx_enable, tx_busy_int, tx_start_int, tx_done_int;
assign tx = data[0];
uart_control uart (
.clk(clk),
.rst_n(rst_n),
.data_in(data),
.tx_busy(tx_busy_int),
.tx_fifo_cnt(),
.tx_fifo_rd_req(),
.tx_fifo_clr_req(),
.tx(tx_enable),
.rx(),
.rx_busy(),
.rx_fifo_cnt(),
.rx_fifo_rd_req(),
.rx_fifo_clr_req()
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
data <= 8'b0;
tx_enable <= 1'b0;
tx_busy_int <= 1'b0;
tx_start_int <= 1'b0;
tx_done_int <= 1'b0;
end else begin
if (tx_start_int) begin
data <= {1'b0, data_in};
tx_start_int <= 1'b0;
tx_done_int <= 1'b0;
end else if (tx_enable && tx_busy_int && tx_done) begin
tx_busy_int <= 1'b0;
tx_done_int <= 1'b1;
end
end
end
endmodule
```
UART 接收模块:
```verilog
module uart_receiver(
input clk, rst_n,
output [7:0] data_out,
input rx
);
reg [7:0] data;
reg rx_enable, rx_busy_int, rx_start_int, rx_done_int;
assign data_out = data;
uart_control uart (
.clk(clk),
.rst_n(rst_n),
.data_in(),
.tx_busy(),
.tx_fifo_cnt(),
.tx_fifo_rd_req(),
.tx_fifo_clr_req(),
.tx(),
.rx(rx_enable),
.rx_busy(rx_busy_int),
.rx_fifo_cnt(),
.rx_fifo_rd_req(),
.rx_fifo_clr_req()
);
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
data <= 8'b0;
rx_enable <= 1'b0;
rx_busy_int <= 1'b0;
rx_start_int <= 1'b0;
rx_done_int <= 1'b0;
end else begin
if (rx_start_int) begin
data <= 8'b0;
rx_enable <= 1'b1;
rx_busy_int <= 1'b0;
rx_start_int <= 1'b0;
rx_done_int <= 1'b0;
end else if (rx_enable && !rx_busy_int) begin
rx_start_int <= 1'b0;
rx_busy_int <= 1'b1;
end else if (rx_enable && rx_busy_int) begin
if (rx_done) begin
rx_busy_int <= 1'b0;
rx_done_int <= 1'b1;
data <= uart.rx_fifo[uart.rx_fifo_rptr];
end
end
end
end
endmodule
```
测试代码:
```verilog
module test_uart();
reg clk, rst_n;
reg [7:0] tx_data;
wire [7:0] rx_data;
wire tx_done, rx_done;
wire tx_busy, rx_busy;
uart_transmitter tx (
.clk(clk),
.rst_n(rst_n),
.data_in(tx_data),
.tx(tx),
.tx_done(tx_done)
);
uart_receiver rx (
.clk(clk),
.rst_n(rst_n),
.data_out(rx_data),
.rx(rx),
.rx_done(rx_done)
);
uart_control uart (
.clk(clk),
.rst_n(rst_n),
.data_in(tx_data),
.data_out(rx_data),
.tx_busy(tx_busy),
.tx_fifo_cnt(),
.tx_fifo_rd_req(),
.tx_fifo_clr_req(),
.tx(tx),
.rx(rx),
.rx_busy(rx_busy),
.rx_fifo_cnt(),
.rx_fifo_rd_req(),
.rx_fifo_clr_req()
);
initial begin
clk = 0;
forever #5 clk = ~clk;
end
initial begin
rst_n = 0;
#10 rst_n = 1;
#10 tx_data = 8'h55;
#10 tx_data = 8'hAA;
#10 tx_data = 8'hFF;
#10 $finish;
end
endmodule
```
这个代码示例中包含了 UART 控制模块、发射模块、接收模块和测试代码的实现。你可以根据需要进行修改和调整。
阅读全文