📄 u_rec.v
字号:
////////////////////////////////////////////////////////////////////////
//
// Abstract: Uart has an auto-tuning baud rate generator
// This is the receiver portion of the UART.
// Module : U_REC.v
//
// Version : ver 01.00
//
// Modification History:
// Date By Change Description
// -----------------------------------------------------------------
// 2008/06/24 jackie
// YYYY/MM/DD author Revision content
//
////////////////////////////////////////////////////////////////////////
`timescale 1ns/1ns
module u_rec (
rst,
uart_clk,
clk,
rxd,
sbuf_r,
ri
);
// Receiver state definition
parameter r_START = 3'b001,
r_CENTER = 3'b010,
r_WAIT = 3'b011,
r_SAMPLE = 3'b100,
r_STOP = 3'b101;
// *****************************
//
// Receiver Configuration
//
// *****************************
// Word length.
// This defines the number of bits
// in a "word". Typcially 8.
// min=0, max=8
parameter WORD_LEN = 8;
parameter delay = 1'b1;
// ******************************************
//
// PORT DEFINITIONS
//
// ******************************************
input rst; // syn reset
input uart_clk; // main clock must be 16 x Baud Rate
input clk;
input rxd; // goes to the UART pin
output [7:0] sbuf_r; // parallel received data
output ri; // when high, new data is ok to be read
// ******************************************
//
// MEMORY ELEMENT DEFINITIONS
//
// ******************************************
reg [2:0] next_state, state;
reg rec_datH, rec_datSyncH;
reg [3:0] bitCell_cntrH;
reg cntr_resetH;
reg [7:0] rec_ShiftRegH;
reg shiftH;
reg [3:0] recd_bitCntrH;
reg countH;
reg rstCountH;
reg rec_readyH;
reg rec_readyInH;
reg uart_clkid;
reg uart_clki;
wire [7:0] sbuf_r;
wire ri;
wire uart_clk_rising;
always @(posedge clk )
if (rst)
begin
uart_clkid <= #delay 1'b1;
uart_clki <= #delay 1'b1;
end
else
begin
uart_clkid <= #delay uart_clk;
uart_clki <= #delay uart_clkid;
end
assign uart_clk_rising = (uart_clkid) && (!uart_clki);
//8 bit parallel data output
assign sbuf_r = rec_ShiftRegH;
// synchronize the asynchrnous input
// to the system clock domain
// dual-rank
always @(posedge clk )
if (rst)
begin
rec_datSyncH <= #delay 1'b1;
rec_datH <= #delay 1'b1;
end
else
begin
rec_datSyncH <= #delay rxd;
rec_datH <= #delay rec_datSyncH;
end
// Bit-cell counter
always @(posedge clk )
if (rst)
bitCell_cntrH <= #delay 1'b0;
else if(uart_clk_rising&&cntr_resetH)
bitCell_cntrH <= #delay 1'b0;
else if(uart_clk_rising)
bitCell_cntrH <= #delay bitCell_cntrH + 1;
// Shifte Register to hold the incoming
// serial data
// LSB is shifted in first
always @(posedge clk )
if (rst)
rec_ShiftRegH <= #delay 1'b0;
else if(uart_clk_rising&&shiftH)
begin
rec_ShiftRegH[6:0] <= #delay rec_ShiftRegH[7:1];
rec_ShiftRegH[7] <= #delay rec_datH;
end
// RECEIVED BIT Counter
// This coutner keeps track of the number of bits received
always @(posedge clk )
if (rst)
recd_bitCntrH <= #delay 1'b0;
else if(uart_clk_rising&&countH)
recd_bitCntrH <= #delay recd_bitCntrH + 1;
else if (uart_clk_rising&&rstCountH)
recd_bitCntrH <= #delay 1'b0;
// State Machine - Next State Assignment
always @(posedge clk )
if (rst)
state <= #delay r_START;
else if(uart_clk_rising)
state <= #delay next_state;
// State Machine - Next State and Output Decode
always @(state or rec_datH or bitCell_cntrH or recd_bitCntrH)
begin
// default
next_state = state;
cntr_resetH = 1'b1;
shiftH = 1'b0;
countH = 1'b0;
rstCountH = 1'b0;
rec_readyInH= 1'b0;
case (state)
// START
// Wait for the start bit
r_START:
begin
if (~rec_datH )
next_state = r_CENTER;
else
begin
next_state = r_START;
rstCountH = 1'b1; // place the bit counter in rst state
rec_readyInH = 1'b1; // by default, we're ready
end
end
// CENTER
// Find the center of the bit-cell
// A bit cell is composed of 16 system-clock ticks
r_CENTER:
begin
if (bitCell_cntrH == 4'h4)
begin
// if after having waited 1/2 bit cell,
// it is still 0, then it is a genuine start bit
if (~rec_datH)
next_state = r_WAIT;
// otherwise, could have been a false noise
else
next_state = r_START;
end
else
begin
next_state = r_CENTER;
cntr_resetH = 1'b0; // allow counter to tick
end
end
// WAIT
// Wait a bit-cell time before sampling the
// state of the data pin
r_WAIT:
begin
if (bitCell_cntrH == 4'hE)
begin
if (recd_bitCntrH == WORD_LEN)
next_state = r_STOP; // we've sampled all 8 bits
else
begin
next_state = r_SAMPLE;
end
end
else
begin
next_state = r_WAIT;
cntr_resetH = 1'b0; // allow counter to tick
end
end
// SAMPLE
// Sample the state of the RECEIVE data pin
r_SAMPLE:
begin
shiftH = 1'b1; // shift in the serial data
countH = 1'b1; // one more bit received
next_state = r_WAIT;
end
// STOP
// make sure that we've seen the stop bit
r_STOP:
begin
next_state = r_START;
rec_readyInH = 1'b1;
end
default:
begin
next_state = 3'bxxx;
cntr_resetH = 1'bx;
shiftH = 1'bx;
countH = 1'bx;
rstCountH = 1'bx;
rec_readyInH = 1'bx;
end
endcase
end
// register the state machine outputs
// to eliminate ciritical-path/glithces
always @(posedge clk)
if (rst)
rec_readyH <= #delay 1'b1;
else
rec_readyH <= #delay rec_readyInH;
assign ri = (!rec_readyH) && rec_readyInH;
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -