단순 UART의 verilog 구현
1. 시스템 시계와 직렬 포트율은 매개 변수로 입력하고 예화할 때 유연하게 설정할 수 있다.
2. 수용 모듈은 시작 위치에서 중점 레벨이 여전히 낮은지 검사하고 그렇지 않으면 떨림으로 판정한다
수신기 코드
`timescale 1ns/1ps
// 200MHz, 115200
module uart_rx #(
parameter BAUDRATE = 115200,
parameter FREQ = 200_000_000)(
input clk, nrst,
input rx,
output reg [7:0] rdata,
output reg vld
);
localparam T = FREQ / BAUDRATE;
// flag , 1
reg flag;
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
flag <= 0;
else if(flag == 0 && rx == 0)
flag <= 1;
else if(cnt_bit == 1 - 1 && cnt_clk == T / 2 - 1 && rx == 1)
flag <= 0;
else if(end_cnt_bit)
flag <= 0;
end
// ,cnt_clk ,cnt_bit 1 ,8 , , 10
reg [3:0] cnt_bit;
reg [31:0] cnt_clk;
assign end_cnt_clk = cnt_clk == T - 1;
assign end_cnt_bit = end_cnt_clk && cnt_bit == 10 - 1;
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
cnt_clk <= 0;
else if(flag) begin
if(end_cnt_clk)
cnt_clk <= 0;
else
cnt_clk <= cnt_clk + 1'b1;
end
else
cnt_clk <= 0;
end
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
cnt_bit <= 0;
else if(end_cnt_clk) begin
if(end_cnt_bit)
cnt_bit <= 0;
else
cnt_bit <= cnt_bit + 1'b1;
end
end
//
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
rdata <= 0;
else if(cnt_clk == T / 2 - 1 && cnt_bit != 1 - 1 && cnt_bit != 10 - 1)
rdata[cnt_bit - 1] <= rx;
end
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
vld <= 0;
else if(end_cnt_bit)
vld <= 1;
else
vld <= 0;
end
endmodule
송신기 코드
`timescale 1ns/1ps
// 200MHz, 115200, rdy
module uart_tx #(
parameter BAUDRATE = 115200,
parameter FREQ = 200_000_000)(
input clk, nrst,
input wrreq,
input [7:0] wdata,
output reg tx,
output reg rdy
);
reg [3:0] cnt_bit;
reg [31:0] cnt_clk;
localparam T = FREQ / BAUDRATE;
// rdy ,
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
rdy <= 1;
else if(wrreq)
rdy <= 0;
else if(end_cnt_bit)
rdy <= 1;
end
// ,cnt_clk ,cnt_bit 1 ,8 , , 10
wire end_cnt_clk;
wire end_cnt_bit;
assign end_cnt_clk = cnt_clk == T - 1;
assign end_cnt_bit = end_cnt_clk && cnt_bit == 10 - 1;
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
cnt_clk <= 0;
else if(rdy == 0) begin
if(end_cnt_clk)
cnt_clk <= 0;
else
cnt_clk <= cnt_clk + 1'b1;
end
end
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
cnt_bit <= 0;
else if(end_cnt_clk) begin
if(end_cnt_bit)
cnt_bit <= 0;
else
cnt_bit <= cnt_bit + 1'b1;
end
end
// 0, 8 , 1
always @(posedge clk or negedge nrst) begin
if(nrst == 0)
tx <= 1;
else if(rdy == 0 && cnt_clk == 0) begin
if(cnt_bit == 1 - 1)
tx <= 0;
else if(cnt_bit == 10 - 1)
tx <= 1;
else
tx <= wdata[cnt_bit - 1];
end
end
endmodule
Xilinx Artix-7 플랫폼에서 검증된 최상위 레벨 코드
`timescale 1ns / 1ps
module uart_top(
input clk_p, clk_n, nrst,
input rx,
output tx
);
localparam BAUDRATE = 115200;
localparam FREQ = 200_000_000;
//
IBUFGDS #(
.DIFF_TERM("FALSE"),
.IBUF_LOW_PWR("TRUE"),
.IOSTANDARD("DEFAULT")
) IBUFGDS_inst(
.O(clk),
.I(clk_p),
.IB(clk_n)
);
wire [7:0] data;
wire vld;
uart_rx #(BAUDRATE, FREQ) uart_rx_u(
.clk (clk ),
.nrst (nrst ),
.rx (rx ),
.rdata (data ),
.vld (vld )
);
uart_tx #(BAUDRATE, FREQ) uart_tx_u(
.clk (clk ),
.nrst (nrst ),
.wrreq (vld ),
.wdata (data ),
.tx (tx ),
.rdy ( )
);
ila_0 ila_0_u(
.clk (clk ),
.probe0 (nrst ),
.probe1 ({tx,rx}),
.probe2 (data ),
.probe3 (vld )
);
endmodule
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.