📄 u_xmit.v
字号:
////////////////////////////////////////////////////////////////////////
//
// Abstract: Uart has an auto-tuning baud rate generator
// This is the transmitter portion of the UART.
// Module : U_XMIT.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_xmit (
uart_clk,
rst,
clk,
txd,
t_st,
sbuf_t,
ti
);
// Xmitter state definition
parameter x_IDLE = 3'b001,
x_START = 3'b010,
x_WAIT = 3'b011,
x_SHIFT = 3'b100,
x_STOP = 3'b101;
parameter x_STARTbit = 2'b00,
x_STOPbit = 2'b01,
x_ShiftReg = 2'b10;
parameter WORD_LEN = 8;
parameter delay = 1'b1;
// ******************************************
//
// PORT DEFINITIONS
//
// ******************************************
input uart_clk; // system clock. Must be 16 x Baud
input rst; // syn reset
input clk;
input t_st; // active high, Xmit command
input [7:0] sbuf_t; // data to be xmitted
output ti; // status
output txd; // this pin goes to the connector
// ******************************************
//
// MEMORY ELEMENT DEFINITIONS
//
// ******************************************
reg [2:0] next_state, state;
reg load_shiftRegH;
reg shiftEnaH;
reg [4:0] bitCell_cntrH;
reg countEnaH;
reg [7:0] xmit_ShiftRegH;
reg [3:0] bitCountH;
reg rst_bitCountH;
reg ena_bitCountH;
reg [1:0] xmitDataSelH;
reg txd;
reg xmit_doneInH;
reg xmit_doneH;
reg uart_clkid;
reg uart_clki;
reg st;
reg st_temp;
reg st_temp2;
wire ti;
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);
//serial data output
always @(xmit_ShiftRegH or xmitDataSelH)
case (xmitDataSelH)
x_STARTbit: txd = 1'b0;
x_STOPbit: txd = 1'b1;
x_ShiftReg: txd = xmit_ShiftRegH[0];
default: txd = 1'bx;
endcase
// Bit Cell time Counter
always @(posedge clk )
if (rst)
bitCell_cntrH <= #delay 1'b0;
else if(uart_clk_rising&&countEnaH)
bitCell_cntrH <= #delay bitCell_cntrH + 1;
else if (uart_clk_rising)
bitCell_cntrH <= #delay 1'b0;
// Shift Register
// The LSB must be shifted out first
always @(posedge clk )
if (rst)
xmit_ShiftRegH <= #delay 1'b0;
else if (uart_clk_rising&&load_shiftRegH)
xmit_ShiftRegH <= #delay sbuf_t;
else if (uart_clk_rising&&shiftEnaH)
begin
xmit_ShiftRegH[6:0] <= #delay xmit_ShiftRegH[7:1];
xmit_ShiftRegH[7] <= #delay 1'b1;
end
else
xmit_ShiftRegH <= #delay xmit_ShiftRegH;
// Transmitted bit counter
always @(posedge clk )
if (rst)
bitCountH <= #delay 1'b0;
else if(uart_clk_rising&&rst_bitCountH)
bitCountH <= #delay 1'b0;
else if(uart_clk_rising&&ena_bitCountH)
bitCountH <= #delay bitCountH + 1;
//modify t_st
always @(posedge clk)
if (rst)
st_temp <= #delay 1'b0;
else if (t_st)
st_temp <= #delay 1'b1;
else if (uart_clk_rising)
st_temp <= #delay 1'b0;
always @(posedge clk )
if(rst)
st_temp2 <= #delay 1'b0;
else if (uart_clk_rising)
st_temp2 <= #delay st_temp;
always @(posedge clk )
if(rst)
st <= #delay 1'b0;
else if (uart_clk_rising)
st <= #delay st_temp2;
// STATE MACHINE
// State Variable
always @(posedge clk )
if (rst)
state <= #delay x_IDLE;
else if(uart_clk_rising)
state <= #delay next_state;
// Next State, Output Decode
always @(state or st or bitCell_cntrH or bitCountH)
begin
// Defaults
next_state = state;
load_shiftRegH = 1'b0;
countEnaH = 1'b0;
shiftEnaH = 1'b0;
rst_bitCountH = 1'b0;
ena_bitCountH = 1'b0;
xmitDataSelH = x_STOPbit;
xmit_doneInH = 1'b0;
case (state)
// x_IDLE
// wait for the start command
x_IDLE:
begin
if (st)
begin
next_state = x_START;
load_shiftRegH = 1'b1;
end
else
begin
next_state = x_IDLE;
rst_bitCountH = 1'b1;
xmit_doneInH = 1'b0;
end
end
// x_START
// send start bit
x_START:
begin
xmitDataSelH = x_STARTbit;
if (bitCell_cntrH == 4'hF)
next_state = x_WAIT;
else
begin
next_state = x_START;
countEnaH = 1'b1; // allow to count up
end
end
// x_WAIT
// wait 1 bit-cell time before sending
// data on the xmit pin
x_WAIT:
begin
xmitDataSelH = x_ShiftReg;
// 1 bit-cell time wait completed
if (bitCell_cntrH == 4'hE)
begin
if (bitCountH == WORD_LEN)
next_state = x_STOP;
else
begin
next_state = x_SHIFT;
ena_bitCountH = 1'b1; //1more bit sent
end
// bit-cell wait not complete
end
else
begin
next_state = x_WAIT;
countEnaH = 1'b1;
end
end
// x_SHIFT
// shift out the next bit
x_SHIFT:
begin
xmitDataSelH = x_ShiftReg;
next_state = x_WAIT;
shiftEnaH = 1'b1; // shift out next bit
end
// x_STOP
// send stop bit
x_STOP:
begin
xmitDataSelH = x_STOPbit;
if (bitCell_cntrH == 4'hF)
begin
next_state = x_IDLE;
xmit_doneInH = 1'b1;
end
else
begin
next_state = x_STOP;
countEnaH = 1'b1; //allow bit cell cntr
end
end
default:
begin
next_state = 3'bxxx;
load_shiftRegH = 1'bx;
countEnaH = 1'bx;
shiftEnaH = 1'bx;
rst_bitCountH = 1'bx;
ena_bitCountH = 1'bx;
xmitDataSelH = 2'bxx;
xmit_doneInH = 1'bx;
end
endcase
end
// register the state machine outputs
// to eliminate ciritical-path/glithces
always @(posedge clk )
if (rst)
xmit_doneH <= #delay 1'b0;
else
xmit_doneH <= #delay xmit_doneInH;
assign ti = (!xmit_doneH) && xmit_doneInH;
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -