//UART串行异步通信
module shiyan1(
input clk,
input reset,
input uart_rx,
output uart_tx);
parameter CLK_FRE = 50;
parameter BAUD_RATE = 115200;
localparam IDLE = 2'd1;
localparam WAIT = 2'd2;
wire rx_data_valid, tx_data_ready;
reg tx_data_valid;
wire [7 : 0] rx_data_out;
reg [1 : 0] s;
reg [7 : 0] tx_data_in;
reg [8 : 0] wait_cnt;
always @(posedge clk or negedge reset)
begin
if(!reset)
begin
wait_cnt <= 9'b0;
s <= IDLE;
tx_data_valid <= 1'b0;
tx_data_in <= 8'b0;
end
else
begin
case(s)
IDLE :
s <= WAIT;
WAIT :
begin
if(rx_data_valid == 1'b1)
begin
tx_data_valid = 1'b1;
tx_data_in <= rx_data_out;
end
else if(tx_data_valid == 1'b1 && tx_data_ready == 1'b1)
tx_data_valid <= 1'b0;
else
wait_cnt <= wait_cnt + 1;
if(wait_cnt >= CLK_FRE * 1000000)
begin
s <= IDLE;
wait_cnt <= 9'b0;
end
end
default :
s <= IDLE;
endcase
end
end
uart_rx #(.CLK_FRE(CLK_FRE), .UART_BPS(BAUD_RATE)) U1 (.clk(clk), .reset(reset), .rx_in(uart_rx), .rx_out(rx_data_out), .rx_data_valid(rx_data_valid));
uart_tx #(.CLK_FRE(CLK_FRE), .UART_BPS(BAUD_RATE)) U2 (.clk(clk), .reset(reset), .tx_data_in(tx_data_in), .tx_data_valid(tx_data_valid), .tx_data_out(tx_data_out), .tx_data_ready(tx_data_ready));
endmodule
module uart_rx #(parameter CLK_FRE = 50, parameter UART_BPS = 115200)
(input clk,
input reset,
input rx_in,
output reg [7 : 0] rx_out,
output reg rx_data_valid);
localparam CYCLE = CLK_FRE * 1000000;
localparam IDLE = 3'd1;
localparam START = 3'd2;
localparam REC_BYTE = 3'd3;
localparam STOP = 3'd4;
wire rx_negedge;
reg rx_in_1, rx_in_2;
reg [2 : 0] s, ns;
reg [3 : 0] bit_i;
reg [7 : 0] rx_bits;
reg [8 : 0] cycle_i;
always @(posedge clk or negedge reset)
begin
if(!reset)
s <= IDLE;
else
s <= ns;
end
always @(posedge clk or negedge reset)
begin
if(!reset)
begin
rx_in_1 <= 0;
rx_in_2 <= 0;
end
else
begin
rx_in_1 <= rx_in;
rx_in_2 <= rx_in_1;
end
end
assign rx_negedge = rx_in_2 && (~ rx_in_1);
always @(*)
begin
case(s)
IDLE :
begin
if(rx_negedge)
ns = START;
else
ns = IDLE;
end
START :
begin
if(cycle_i == CYCLE - 1)
ns = REC_BYTE;
else
ns = START;
end
REC_BYTE :
begin
if(cycle_i == CYCLE - 1 && bit_i == 3'd7)
ns = STOP;
else
ns = REC_BYTE;
end
STOP :
begin
if(cycle_i == (CYCLE >> 1) - 1)
ns = IDLE;
else
ns = STOP;
end
default :
ns = STOP;
endcase
end
always @(posedge clk or negedge reset)
begin
if(!reset)
cycle_i <= 9'b0;
else if(s != ns || (s == REC_BYTE && cycle_i == CYCLE - 1))
cycle_i <= 9'b0;
else
cycle_i <= cycle_i + 9'b1;
end
always @(posedge clk or negedge reset)
begin
if(!reset)
bit_i <= 3'b0;
else if(s == REC_BYTE)
begin
if(cycle_i == CYCLE - 1)
bit_i <= bit_i + 3'b1;
else
bit_i <= bit_i;
end
else
bit_i <= 3'b0;
end
always @(posedge clk or negedge reset)
begin
if(!reset)
rx_bits <= 8'b0;
else if(s == REC_BYTE && cycle_i == (CYCLE >> 1) - 1)
rx_bits[bit_i] <= rx_in;
else
rx_bits <= rx_bits;
end
always @(posedge clk or negedge reset)
begin
if(!reset)
rx_out <= 8'b0;
else if(s == STOP && ns != s)
rx_out <= rx_bits;
end
always @(posedge clk or negedge reset)
begin
if(!reset)
rx_data_valid <= 1'b0;
else if(s == STOP && s != ns)
rx_data_valid <= 1'b1;
else
rx_data_valid <= 1'b0;
end
endmodule
module uart_tx #(parameter CLK_FRE = 50, parameter UART_BPS = 115200)
(input clk,
input reset,
input tx_data_valid,
input [7 : 0] tx_data_in,
output tx_data_out,
output reg tx_data_ready
);
localparam CYCLE = CLK_FRE * 1000000;
localparam IDLE = 3'd1;
localparam START = 3'd2;
localparam SEND_BYTE = 3'd3;
localparam STOP = 3'd4;
reg tx_data_reg;
reg [2 : 0] s, ns;
reg [3 : 0] bit_i;
reg [7 : 0] tx_data_latch;
reg [8 : 0] cycle_i;
always @(posedge clk or negedge reset)
begin
if(!reset)
s <= IDLE;
else
s <= ns;
end
always @(*)
begin
case(s)
IDLE :
begin
if(tx_data_valid == 1'b1)
ns = START;
else
ns = IDLE;
end
START :
begin
if(cycle_i == CYCLE - 1)
ns = SEND_BYTE;
else
ns = START;
end
SEND_BYTE :
begin
if(bit_i == 3'd7 && cycle_i == CYCLE - 1)
ns = STOP;
else
ns = SEND_BYTE;
end
STOP :
begin
if(cycle_i == CYCLE - 1)
ns = IDLE;
else
ns = STOP;
end
default :
ns = IDLE;
endcase
end
always @(posedge clk or negedge reset)
begin
if(!reset)
cycle_i <= 9'b0;
else if(s != ns || (s == SEND_BYTE && cycle_i == CYCLE - 1))
cycle_i <= 9'b0;
else
cycle_i <= cycle_i + 9'b1;
end
always @(posedge clk or negedge reset)
begin
if(!reset)
bit_i <= 9'b0;
else if(s == SEND_BYTE)
begin
if(cycle_i == CYCLE - 1)
bit_i <= bit_i + 3'b1;
else
bit_i <= bit_i;
end
else
bit_i <= 3'b0;
end
always @(posedge clk or negedge reset)
begin
if(!reset)
tx_data_latch <= 8'b0;
else if(s == IDLE && tx_data_valid == 1'b1)
tx_data_latch <= tx_data_in;
end
always @(posedge clk or negedge reset)
begin
if(!reset)
tx_data_reg <= 1'b1;
else
begin
case(s)
IDLE, STOP :
tx_data_reg <= 1'b1;
START :
tx_data_reg <= 1'b0;
SEND_BYTE :
tx_data_reg <= tx_data_latch[bit_i];
default :
tx_data_reg <= 1'b1;
endcase
end
end
assign tx_data_out = tx_data_reg;
always @(posedge clk or negedge reset)
begin
if(!reset)
tx_data_ready <= 1'b0;
else if(s == STOP && cycle_i == CYCLE - 1)
tx_data_ready <= 1'b1;
else if(s == IDLE)
if(tx_data_valid == 1)
tx_data_ready <= 1'b0;
else
tx_data_ready <= 1'b1;
end
endmodule
Verilog之UART串口通信
最新推荐文章于 2024-07-24 23:22:05 发布