uart232串列埠之二——fpg內部迴環模擬
該模組功能, 接收資料。
module rs232_rx_cnt(
clk,
rst_n,
sel_bps,
uart_rx,
rx_done,
data_recv);
input clk;
input rst_n;
input uart_rx;
input [2:0] sel_bps;
output rx_done;
output [7:0] data_recv;
reg [11:0] cnt1;//第一階段計數器
reg [12:0] cnt2;
reg [12:0] Time;
always @(*) begin
if (sel_bps == 3'd0)
Time <= 5208; //9600
else if (sel_bps == 3'd1)
Time <= 1302; //38400
else if (sel_bps == 3'd2)
Time <= 434; //115200
else
Time <= 5208;
end
reg rx1,rx2;
always @ (posedge clk or negedge rst_n) begin
if ( rst_n == 1'b0) begin
rx1 <= 1'b0;
rx2 <= 1'b0;
end
else if (sta ==IDLE)
begin
rx1 <= uart_rx;
rx2 <= rx1;
end
else begin
rx1 <= 1'b0;
rx2 <= 1'b0;
end
end
assign start = !rx1 & rx2;
reg [1:0] sta;
parameter IDLE=2'd0;
parameter S1=2'd1;
parameter S2=2'd2;
always @ (posedge clk or negedge rst_n) begin
if (rst_n ==1'b0)
sta <= IDLE;
else
begin
case(sta)
IDLE: begin
if (start==1'b1)
sta <= S1;
else
sta <= IDLE;
end
S1: begin
if (cnt1== Time[11:1])
sta <= S2;
else
sta <= S1;
end
S2: begin
if (rx_done == 1'b1)
sta <= IDLE;
else
sta <= S2;
end
endcase
end
end
always @ (posedge clk or negedge rst_n) begin
if (rst_n ==1'b0)
cnt1 <= 12'd0;
else if (sta==S1)
begin
if (cnt1== Time[11:1])
cnt1 <= 12'd0;
else
cnt1 <= cnt1 + 1'b1;
end
else
begin
cnt1 <= 12'd0;
end
end
//週期性cnt2, 產生取樣脈衝
reg pulse_sample ;
always @ (posedge clk or negedge rst_n) begin
if (rst_n ==1'b0)
begin
cnt2 <= 13'd0;
pulse_sample <= 1'b0;
end
else if (sta == S2) begin
if (cnt2 == Time-1)
begin
cnt2 <= 13'd0;
pulse_sample <= 1'b1;
end
else
begin
cnt2 <= cnt2 + 1'd1;
pulse_sample <= 1'b0;
end
end
else
begin
cnt2 <= 13'd0;
pulse_sample <= 1'b0;
end
end
//根據取樣脈衝,接收資料
reg [7:0] data_buf;
always @ (posedge clk or negedge rst_n) begin
if (rst_n ==1'b0)
data_buf <= 8'd0;
else
if (sta == S2)
begin
if (pulse_sample == 1'b1)
begin
// data_recv <= {data_recv[6:0], uart_rx};
data_buf <= {uart_rx, data_buf[7:1]};
end
else
data_buf <= data_buf;
end
else
data_buf <= 8'd0;
end
reg [3:0] cnt3;
always @ (posedge clk or negedge rst_n)
if (rst_n ==1'b0)
cnt3 <= 3'd0;
else
begin
if (sta == S2)
begin
if (cnt2 == Time-1)
cnt3 <= cnt3 + 1'b1;
else
cnt3 <= cnt3;
end
else
cnt3 <= 3'd0;
end
//assign rx_done = ((cnt2 == Time-1) && (cnt3 == 3'd8));
assign rx_done = ((cnt2 == Time-1) && (cnt3 == 4'd8));
assign data_recv = rx_done ? data_buf: data_recv;
endmodule
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
這裡是傳送模組
module rs232_tx_cnt(
Clk,
rst_n,
en_go,
tx_done,
sel_bps,
Data,
uart_tx);
input Clk;
input rst_n;
input en_go;
output tx_done;
input [2:0] sel_bps;
input [7:0] Data;
output reg uart_tx;
reg [20:0] Time;
reg [31:0] counter;
reg [3:0] counter2;
wire bps_Start;
reg en;
always @(*) begin
if (sel_bps == 3'd0)
Time <= 5208; //9600
else if (sel_bps == 3'd1)
Time <= 1302; //38400
else if (sel_bps == 3'd2)
Time <= 434; //115200
else
Time <= 5208;
end
always @(posedge Clk or negedge rst_n) begin
if ( rst_n == 1'b0)
en <= 0;
else if (en_go == 1'b1)
en <= 1;
else if (tx_done == 1'b1)
en <= 0;
else
en <= en;
end
reg [7:0] R_Data;
always @(posedge Clk or negedge rst_n) begin
if ( rst_n == 1'b0)
R_Data <= 0;
else if (en_go == 1'b1)
R_Data <= Data;
else
R_Data <= R_Data;
end
//bps產生
always @(posedge Clk or negedge rst_n) begin
if ( rst_n == 1'b0)
counter <= 0;
else if (en == 1'b1)
begin
if (counter == Time - 1)
counter <= 0;
else
counter <= counter + 1'd1;
end
else
counter <= 0;
end
assign bps_Start = ((counter == 0) && (en==1'b1));
always @(posedge Clk or negedge rst_n) begin
if ( rst_n == 1'b0)
counter2 <= 0;
else if( en == 1'b1)
begin
if (tx_done)
counter2 <=0;
else if (counter == Time - 1)
counter2 <= counter2 + 1'b1;
else
counter2 <= counter2;
end
else
counter2 <= 0;
end
assign tx_done = ((counter2 == 9) && (counter == Time - 1));
always @(posedge Clk or negedge rst_n) begin
if (rst_n == 1'b0)
uart_tx <= 1'b1;
else if ( en ==1'b1) begin
case(counter2 )
0: uart_tx <= 1'b0;
1: uart_tx <= R_Data[0];
2: uart_tx <= R_Data[1];
3: uart_tx <= R_Data[2];
4: uart_tx <= R_Data[3];
5: uart_tx <= R_Data[4];
6: uart_tx <= R_Data[5];
7: uart_tx <= R_Data[6];
8: uart_tx <= R_Data[7];
9: uart_tx <= 1'b1;
default : uart_tx <= 1'b1;
endcase
end
else
uart_tx <= 1'b1;
end
endmodule
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
這裡是頂層檔案
`timescale 1ns/1ps
module top(clk, Rest_n,uart_tx ) ;
input Rest_n;
input clk;
output uart_tx;
reg [7:0] data;
//wire tx_done;
reg en_go;
reg [20:0] cnt;
rs232_tx_cnt u2(
.Clk(clk),
.rst_n(Rest_n),
.en_go(en_go),
.tx_done(),
.sel_bps(3'd2),//
.Data(data),
.uart_tx(uart_tx)
);
always @(posedge clk or negedge Rest_n) begin
if ( Rest_n == 1'b0) begin
en_go <= 0;
data <= 8'h54;
end
else if( cnt == 1) begin
en_go <= 1'b1;
data <=data+1'd1;
end
else en_go <= 1'b0;
end
always @(posedge clk or negedge Rest_n) begin
if ( Rest_n == 1'b0)
cnt <= 0;
//else if( cnt == 50000000 -1) //
else if( cnt == 50000 -1) //for simualato
cnt <= 0;
else
cnt <= cnt + 1'd1;
end
wire [7:0] data_recv;
rs232_rx_cnt u3(
.clk(clk),
.rst_n(Rest_n),
.sel_bps(3'd2),
.uart_rx(uart_tx),
.rx_done(),
.data_recv(data_recv)
);
endmodule
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
下面是 測試的tb檔案
module top_tb();
reg clk;
reg rst_n;
wire uart_tx;
initial clk = 1;
initial begin
rst_n= 0;
#201; rst_n=1;
#10000000;
$stop;
end
top u1(.clk(clk),
.Rest_n(rst_n),
.uart_tx (uart_tx)) ;
always #10 clk = ~clk;//50Mhz 時鐘
endmodule
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
執行之後,下面的模擬結果的圖:
從圖上發現,rx_done完成訊號,有一個脈衝之後,data_recv是收到的資料0x55. tb檔案裡面傳送的是順序數,因此,下一個資料是55,56.。。。。
說明串列埠的接收模組也能正常的接收資料了。
- 用Python講述:地理“經緯度”資料的4種轉換方法!
- 17 張程式設計師桌布(使用頻率很高)
- [總結]高效能人士的七個習慣
- 為什麼你的程式總是出現 bug?
- GB28181協議錯誤碼返回碼整理
- 還在用 Windows 自帶的搜尋工具嗎?你 out 啦!
- 動畫: 一個瀏覽器是如何工作的?
- 8小時刪除,這波資源碉堡了 ! @所有人
- 新手上路第一篇C語言部落格
- ESP8266_NONOS_SDK--UART實驗
- 2021-01-05
- 《軟體架構》總覽
- 修改Exchange資訊儲存佔用記憶體大小
- uart232串列埠之二——fpg內部迴環模擬
- 3.18PMP試題每日一題
- 2020-12-28
- 一文詳細講解SQL語句中可以提高執行效率的方法
- 小程式開發遇到的坑,知道下總是好的!
- 如何通過 Spring 框架進行JDBC操作?
- GSYVideoPlayer播放器框架使用、播放元件原始碼探究(一)