?? rxcver.v
字號:
/*******************************************************************
*
* DESCRIPTION: UART receiver module.
*
* AUTHOR: Thomas Oelsner
*
* HISTORY: 10/04/96
*
*******************************************************************/
module rxcver (mclkx16, read, rx, reset, rxrdy, parityerr, framingerr, overrun, data);
input mclkx16; // Input clock, 16 x baudrate clock used for synchronisation.
input read; // Read strobe.
input rx; // Receive input line.
input reset; // Global Reset.
// receive status & error signals
output rxrdy; // Received data ready to be read.
output parityerr; reg parityerr; // Receiver parity error detected.
output framingerr; reg framingerr; // Receiver framing error detected.
output overrun; reg overrun; // Receiver overrun error detected.
// 8 bit latched output data bus.
output [7:0] data; reg [7:0]data; // 8 bit output data bus
// Internal control signals.
reg [3:0] rxcnt; // Count of clock cycles
reg rx1, read1, read2, idle1, hunt; // Delayed versions of rx, read, idle, and last hunting for start bit flag.
// Receive shift register bits
reg [7:0] rhr; // Receive hold register
reg [7:0] rsr; // Receive seriel -> parallel shift register
reg rxparity; // Parity bit of received data
reg paritygen; // Generated parity of received data
reg rxstop; // Stop bit of received data
//wire paritymode = 1'b1; // Initializing to 1 = odd parity, 0 = even parity.
// Receive clock and control signals.
reg rxclk; // Receive data shift clock
reg idle; // 1'b1 when receiver is idling
reg rxdatardy; // 1'b1 when data is ready to be read
// Idle requires async preset since it is clocked by rxclk, and it's
// value determines whether rxclk gets generated or not.
// Idle goes low when shifting in data. This is ensured because all bits
// of rsr are preset to all 1's when idle is high. Idle goes high again
// when rsr[0] = 0, i.e. when the low "rxstop" bit reach rsr[0].
// Next rising edge of rxclk preset idle to high again, and generation of
// rxclk is disabled.
always @(posedge rxclk or posedge reset)
begin
if (reset)
idle <= 1'b1;
else
idle <= !idle && !rsr[0];
end
// Synchronizing rxclk to the centerpoint of low leading startbit.
always @(posedge mclkx16)
begin
// A start bit is eight clock times with rx=0 after a falling edge of rx.
if (reset)
hunt <= 1'b0;
else if (idle && !rx && rx1 )
hunt <= 1'b1; // Start hunting when idle and falling edge of rx is found.
else if (!idle || rx )
hunt <= 1'b0; // Stop hunting when shifting in data, or a 1 is found on rx.
if (!idle || hunt)
rxcnt <= rxcnt + 1; // Count clocks when not idle, or hunting for start bit.
else
rxcnt <= 4'b0001; // hold at 1, when idle and waiting for falling edge of rx.
rx1 <= rx; // delay rx one cycle of mclkx16, used for edge detection.
rxclk <= rxcnt[3]; // rxclk = mclkx16 divided by 16. First rising edge of rxclk occures
// always at the centerpoint of the low leading startbit.
end
// This task reset internal bit of receiver, when no data are received.
task idle_reset;
begin
rsr <= 8'b11111111; // All 1's ensure that idle stays low during data shifting.
rxparity <= 1'b1; // Preset to high to ensure idle = 0 during data shifting.
// paritygen <= paritymode; // Preset paritygen to parity mode.
paritygen <= 1'b1; // Preset to 1 => odd parity mode, 0 => even parity mode.
rxstop <= 1'b0; // Forces idle = 1, when rsr[0] gets rxstop bit.
end
endtask
// This task executes sampling & shifting of data, and generates parity result.
task shift_data;
begin
rsr <= rsr >> 1; // Right shift receive shift register.
rsr[7] <= rxparity; // Load rsr[7] with rxparity.
rxparity <= rxstop; // Load rxparity with rxstop.
rxstop <= rx; // Load rxstop with rx. At 1'st shift rxstop gets low "start bit".
paritygen <= paritygen ^ rxstop; // Generate parity as data are shifted.
end
endtask
// When not idling, sample data at the rx input, and generate parity.
always @(posedge rxclk or posedge reset)
if (reset)
idle_reset; // Reset internal bits.
else
begin
if (idle)
idle_reset; // Reset internal bits.
else
shift_data; // Shift data and generate parity.
end
// Generate status & error flags.
always @(posedge mclkx16 or posedge reset)
if (reset)
begin
rhr <= 8'h00;
rxdatardy <= 1'b0;
overrun <= 1'b0;
parityerr <= 1'b0;
framingerr <= 1'b0;
idle1 <= 1'b1;
read2 <= 1'b1;
read1 <= 1'b1;
end
else
begin
if (idle && !idle1) // Look for rising edge of idle and update output registers.
begin
if (rxdatardy)
overrun <= 1'b1; // Overrun error, if previous data still in holding register.
else
begin
overrun <= 1'b0; // No overrun error, since holding register is empty.
rhr <= rsr; // Update holding register with contens of shift register.
parityerr <= paritygen; // paritygen = 1, if parity error.
framingerr <= !rxstop; // Framingerror, if stop bit is not 1.
rxdatardy <= 1'b1; // Data is ready for reading flag.
end
end
if (!read2 && read1)
begin // Clear error and data registers when data is read.
rxdatardy <= 1'b0;
parityerr <= 1'b0;
framingerr <= 1'b0;
overrun <= 1'b0;
end
idle1 <= idle; // idle delayed 1 cycle for edge detect.
read2 <= read1; // 2 cycle delayed version of read, used for edge detection.
read1 <= read; // 1 cycle delayed version of read, used for edge detection.
end
assign rxrdy = rxdatardy; // Receive data ready output signal
always @(read or rhr) //Latch data output when read goes low.
if (~read)
data = rhr;
endmodule
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -