标签:使用 cas ram verilog route 标记 传输数据 str 警告
略……(后续会补上)
略……(后续会补上)
下面先介绍UART关键的3个模块,可以先不理解其中的工作原理,先了解这几个模块的作用与效果。
/* Uart时钟信号 */
module Uart_ClkDiv(
input Sys_CLK, //50Mhz系统时钟
output Uart_CLK //9600bps
);
上述Uart_ClkDiv用来生成Uart传输所需要的时钟信号,输入50Mhz系统时钟,输出Uart时钟
/* Uart_Rx 用于接收数据 */
module Uart_Rx(
input Uart_CLK,//采样时钟
input RST,//复位信号
input Signal_Rx,//UART数据输入
output reg [7:0] Data_Rx,//接收数据输出
output reg Rdsig,//置1时表示上层模块已经可以读8位数据了
output reg DataError_Flag,//数据出错指示
output reg FrameError_Flag//帧出错指示
);
上述Uart_Rx用于接收数据,输入的Uart_CLK为模块Uart_ClkDiv生成的Uart时钟信号,RST为复位键信号(低电平有效),Signal_Rx为Uart数据输入信号
8bit输出Data_Rx为一次接收获取的数据,Rdsig为低电平表示正在接收数据,当一次数据接收完毕后会置成一段时间的高电平
DataError_Flag和FrameError_Flag都是出错提示,当接收数据过程发送错误会被置成高电平,需要注意此处的校验位为偶校验位(Even)
/* Uart_Tx发送数据 */
module Uart_Tx(
input Uart_CLK,
input RST,
input [7:0] Data_Tx,//8位待发送数据
input Wrsig,
output reg Idle,//空闲状态,0表示空闲,1表示忙碌
output reg Signal_Tx//并转串,1位输出
);
上述Uart_Tx用于发送数据,输入的Uart_CLK为模块Uart_ClkDiv生成的Uart时钟信号,RST为复位键信号(低电平有效)
Data_Tx为8bit待发送数据,Wrsig上升沿时开始发送
Idle是Uart_Tx发送器的状态,0表示空闲,1表示忙碌, Signal_Tx是数据输出信号
上述三个模块是UART发送的核心,但要实现超过8位的数据传输,单靠上面还不够
由于UART的资料位(数据位)一般是8位,但实际应用中需要传输多位数据。根据Uart_Rx和Uart_Tx各接口的效果,使用时钟周期进行循环接收与发送
此处以接收64bit数据,并将接收到的数据发送为例,演示多位数据传输的原理
注意:图中的校验位为EVEN,应该为偶校验,猜测软件将EVEN(偶)标记成EVEN(奇)
/* 顶层模块 */
module uart_top(
input sys_clk,//系统时钟
input sys_rst,//复位键
input signal_rx,//接收信号rx
input enable,//使能信号
output isEnable,//是否能够运行
output Err,//错误信号
output busy,//忙碌信号
output finish,//完成信号
output signal_tx//tx发送信号
);
上述为顶层模块的接口,由于代码实现的原因,在每次发送数据至 FPGA 板子前需要按下复位键,否则将无法正常接收
运行中信号,错误信号,忙碌信号,完成信号分别绑在FPGA的4个LED灯中,作为FPGA传输数据时的反馈
使能信号enable绑于一个拨码开关上,高电平运行
/* 循环接收模块 */
module Uart_Receive_Top(
input sys_clk,//系统时钟
input sys_rst,//系统复位键
input signal_rx,//接收信号rx
input enable,//使能信号
output reg[63:0] data_input,//数据输入
output reg Err,//报错,高电平出错
output reg finish,//接收完成信号
output reg busy//高电平忙碌
);
上述是接收模块的接口定义,在此模块中实现循环接收数据,接收完毕后会将finish信号置1,表示接收完成
如果接收未完成,busy信号为1,如果接收出错,Err信号为1
/* 循环接收模块 */
case(state)
4‘d00 : begin
if(Rdsig && !DataError && !FrameError) begin
data_input[64-0*8-1:64-(0+1)*8] <= data_rx;
busy <= 1‘b1;
state <= state + 1;
end
else if(DataError || FrameError) begin
Err <= 1;
state <= 4‘b1111;
end
end
4‘d01 : begin
if(!Rdsig)state <= state + 1;
end
4‘d02 : begin
if(Rdsig && !DataError && !FrameError) begin
data_input[64-1*8-1:64-(1+1)*8] <= data_rx;
busy <= 1‘b1;
state <= state + 1;
end
else if(DataError || FrameError) begin
Err <= 1;
state <= 4‘b1111;
end
end
4‘d03 : begin
if(!Rdsig)state <= state + 1;
end
...
4‘d14 : begin
if(Rdsig && !DataError && !FrameError) begin
data_input[64-7*8-1:64-(7+1)*8] <= data_rx;
finish <= 1;
busy <= 0;
state <= state;
end
else if(DataError || FrameError) begin
Err <= 1;
state <= 4‘b1111;
end
end
//报错
4‘b1111:Err<=1;
default:;
endcase
上述是接收过程的其中几个状态,每两个状态完成一次接收操作
第一个状态进行接收,当Rwsig为1是表示接收完毕,DataError和FrameError都不为0表示未发生错误
故一次接收完成,进行data_input的赋值,并让state + 1跳转至下一个状态;如果发生错误,将状态跳转到报错状态
第二个状态等待下一次接收的开始,当Rwsig为0后表明接收开始,跳转到下一个状态等待接收完毕
当最后一个数据接收完毕后,将finish置1,busy置0,表明接收完毕
module Uart_Send_Top(
input sys_clk,//系统时钟50MHz
input sys_rst,//重置键rst
input [63:0] data_output,//待发送数据
input enable,//发送使能,1为可以发送
output wire signal_tx,//uart发送信号tx
output reg Err,//报错,高电平出错
output reg finish,//完成信号
output reg busy//高电平时表示忙碌
);
上述是循环发送模块的接口定义,与接收接口类似
/* 循环发送模块 */
case(state)
4‘d00 : begin
if(!Busy_Tx) begin
Data_Tx <= data_output[64-0*8-1:64-(0+1)*8];
Wrsig <= 1;
state <= state + 1;
wait_cnt <= 12‘d0;
wait_finished <= 1‘b0;
end
end
4‘d01 : begin
if(Busy_Tx) begin
Wrsig <= 0;
end
else begin
wait_cnt <= wait_cnt + 1;
if(wait_cnt == 12‘hA00) begin
wait_cnt <= 12‘d0;
wait_finished <= 1‘b1;
end
else if(wait_cnt == 12‘d0 && wait_finished) state <= state + 1;
end
end
4‘d02 : begin
if(!Busy_Tx) begin
Data_Tx <= data_output[64-1*8-1:64-(1+1)*8];
Wrsig <= 1;
state <= state + 1;
wait_cnt <= 12‘d0;
wait_finished <= 1‘b0;
end
end
4‘d03 : begin
if(Busy_Tx) begin
Wrsig <= 0;
end
else begin
wait_cnt <= wait_cnt + 1;
if(wait_cnt == 12‘hA00) begin
wait_cnt <= 12‘d0;
wait_finished <= 1‘b1;
end
else if(wait_cnt == 12‘d0 && wait_finished) state <= state + 1;
end
...
4‘d14 : begin
if(!Busy_Tx) begin
Data_Tx <= data_output[64-7*8-1:64-(7+1)*8];
Wrsig <= 1;
state <= state + 1;
wait_cnt <= 12‘d0;
wait_finished <= 1‘b0;
end
end
4‘d15 : begin
if(Busy_Tx) begin
Wrsig <= 0;
end
else begin
wait_cnt <= wait_cnt + 1;
if(wait_cnt == 12‘hA00) begin
wait_cnt <= 12‘d0;
wait_finished <= 1‘b1;
end
else if(wait_cnt == 12‘d0 && wait_finished) begin//发送完成
finish <= 1;
busy <= 0;
end
end
end
default:;
endcase
上述是发送过程的几个状态,同接收类似,每两个状态完成一次发送
第一个状态是发送数据,当Busy_Tx为0,即发送器空闲时,传入发送数据,并产生Wrsig高电平启动信号
设置wait_cnt的原因是两次发送最好有一个码元的间隔,当传输发送数据后,wait_cnt和wait_finished都置0,开始计数,并跳转到下一个状态
第二个状态等待将Wrsig置回0,完成一次启动信号的发生;当传输完毕,发送器变回空闲状态(Busy_Tx=0)时,开始计数
计数完毕后,跳转至下一个状态
最后一个状态结束后不再跳转,将finish置成1,busy置成0,其他保持不变
通过上述两个循环,完成对数据的接收与发送
综合过程中可能会出现如下warning,这是由于我们使用了Uart_CLK代替了系统时钟,会产生警告(可忽略)
Route:455 - CLK Net:Uart_Send_Top/module_ClkDiv/Uart_CLK may have excessive skew
引脚定义如下
module uart_top(
input sys_clk,//系统时钟
input sys_rst,//复位键
input signal_rx,//接收信号rx
input enable,//使能信号
output isEnable,//是否能够运行
output Err,//错误信号
output busy,//忙碌信号
output finish,//完成信号
output signal_tx//tx发送信号
);
wire [63:0] data;
wire finish_receive;
/* uart接收 */
wire err_rx;
wire busy_rx;
Uart_Receive_Top Uart_Receive_Top(
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.signal_rx(signal_rx),
.enable(enable),
.data_input(data),
.Err(err_rx),
.busy(busy_rx),
.finish(finish_receive)
);
/* uart发送 */
wire err_tx;
wire busy_tx;
Uart_Send_Top Uart_Send_Top(
.sys_clk(sys_clk),
.sys_rst(sys_rst),
.data_output(data),
.enable(finish_receive),
.signal_tx(signal_tx),
.Err(err_tx),
.finish(finish),
.busy(busy_tx)
);
assign busy = busy_rx | busy_tx ;
assign Err = err_rx | err_tx;
assign isEnable = enable;
endmodule
module Uart_Receive_Top(
input sys_clk,//系统时钟
input sys_rst,//系统复位键
input signal_rx,//接收信号rx
input enable,//使能信号
output reg[63:0] data_input,//加解密文输入
output reg Err,//报错,高电平出错
output reg finish,//接收完成信号
output reg busy//高电平忙碌
);
/* uart时钟信号产生 */
wire uart_clk;
Uart_ClkDiv module_ClkDiv(
.Sys_CLK(sys_clk),
.Uart_CLK(uart_clk)
);
/* 接收模块 */
wire[7:0] data_rx;//接收数据缓存
wire Rdsig;//读使能,高电平时可以从8位缓存中读取数据
wire DataError;//数据错误信号,高电平时出错
wire FrameError;//帧错误信号,高电平时出错
Uart_Rx module_Rx(
.Uart_CLK(uart_clk),
.RST(sys_rst),
.Signal_Rx(signal_rx),
.Data_Rx(data_rx),
.Rdsig(Rdsig),
.DataError_Flag(DataError),
.FrameError_Flag(FrameError)
);
/* 状态机 */
reg [3:0] state;
always@(posedge sys_clk or negedge sys_rst) begin
if(~sys_rst) begin
Err <= 0;
finish <= 0;
busy <= 0;
data_input <= 64‘b0;
state <= 4‘b0;
end
else if(~enable) begin
Err <= 0;
finish <= 0;
busy <= 0;
data_input <= 64‘b0;
state <= 4‘b0;
end
else begin
case(state)
//读取64bit 的data_input
4‘d00 : begin
if(Rdsig && !DataError && !FrameError)begin
data_input[64-0*8-1:64-(0+1)*8] <= data_rx;
busy <= 1‘b1;
state <= state + 1; end
else if(DataError || FrameError) begin
Err <= 1;
state <= 4‘b1111;
end
end
4‘d01 : begin
if(!Rdsig)state <= state + 1;
end
4‘d02 : begin
if(Rdsig && !DataError && !FrameError)begin
data_input[64-1*8-1:64-(1+1)*8] <= data_rx;
busy <= 1‘b1;
state <= state + 1; end
else if(DataError || FrameError) begin
Err <= 1;
state <= 4‘b1111;
end
end
4‘d03 : begin
if(!Rdsig)state <= state + 1;
end
4‘d04 : begin
if(Rdsig && !DataError && !FrameError)begin
data_input[64-2*8-1:64-(2+1)*8] <= data_rx;
busy <= 1‘b1;
state <= state + 1; end
else if(DataError || FrameError) begin
Err <= 1;
state <= 4‘b1111;
end
end
4‘d05 : begin
if(!Rdsig)state <= state + 1;
end
4‘d06 : begin
if(Rdsig && !DataError && !FrameError)begin
data_input[64-3*8-1:64-(3+1)*8] <= data_rx;
busy <= 1‘b1;
state <= state + 1; end
else if(DataError || FrameError) begin
Err <= 1;
state <= 4‘b1111;
end
end
4‘d07 : begin
if(!Rdsig)state <= state + 1;
end
4‘d08 : begin
if(Rdsig && !DataError && !FrameError)begin
data_input[64-4*8-1:64-(4+1)*8] <= data_rx;
busy <= 1‘b1;
state <= state + 1; end
else if(DataError || FrameError) begin
Err <= 1;
state <= 4‘b1111;
end
end
4‘d09 : begin
if(!Rdsig)state <= state + 1;
end
4‘d10 : begin
if(Rdsig && !DataError && !FrameError)begin
data_input[64-5*8-1:64-(5+1)*8] <= data_rx;
busy <= 1‘b1;
state <= state + 1; end
else if(DataError || FrameError) begin
Err <= 1;
state <= 4‘b1111;
end
end
4‘d11 : begin
if(!Rdsig)state <= state + 1;
end
4‘d12 : begin
if(Rdsig && !DataError && !FrameError)begin
data_input[64-6*8-1:64-(6+1)*8] <= data_rx;
busy <= 1‘b1;
state <= state + 1; end
else if(DataError || FrameError) begin
Err <= 1;
state <= 4‘b1111;
end
end
4‘d13 : begin
if(!Rdsig)state <= state + 1;
end
4‘d14 : begin
if(Rdsig && !DataError && !FrameError)begin
data_input[64-7*8-1:64-(7+1)*8] <= data_rx;
finish <= 1;
busy <= 0;
state <= state;
end
else if(DataError || FrameError) begin
Err <= 1;
state <= 4‘b1111;
end
end
//报错
4‘b1111:Err<=1;
default:;
endcase
end
end
endmodule
module Uart_Send_Top(
input sys_clk,//系统时钟50MHz
input sys_rst,//重置键rst
input [63:0] data_output,//待发送数据
input enable,//发送使能,1为可以发送
output wire signal_tx,//uart发送信号tx
output reg Err,//报错,高电平出错
output reg finish,//完成信号
output reg busy//高电平时表示忙碌
);
/* uart时钟信号产生 */
wire uart_clk;
Uart_ClkDiv module_ClkDiv(
.Sys_CLK(sys_clk),
.Uart_CLK(uart_clk)
);
/* 发送模块 */
reg [7:0] Data_Tx;//待发送8位数据
reg Wrsig;//写使能,上升沿有效
wire Busy_Tx;//1时忙碌,0时空闲
Uart_Tx module_Tx(
.Uart_CLK(uart_clk),
.RST(sys_rst),
.Data_Tx(Data_Tx),
.Wrsig(Wrsig),
.Idle(Busy_Tx),
.Signal_Tx(signal_tx)
);
/* 状态机 */
reg [3:0] state;
reg[11:0] wait_cnt;//等待时使用的计数器
reg wait_finished;//1表示完成等待
always@(posedge sys_clk or negedge sys_rst) begin
if(~sys_rst) begin
Err <= 0;
finish <= 0;
busy <= 0;
state <= 4‘b0;
wait_cnt <= 12‘b0;
wait_finished <= 0;
Data_Tx <= 8‘b0;
end
else if(~enable) begin
Err <= 0;
finish <= 0;
busy <= 0;
state <= 4‘b0;
wait_cnt <= 12‘b0;
wait_finished <= 0;
Data_Tx <= 8‘b0;
end
else begin
case(state)
4‘d00 : begin
if(!Busy_Tx) begin
Data_Tx <= data_output[64-0*8-1:64-(0+1)*8];
Wrsig <= 1;
state <= state + 1;
wait_cnt <= 12‘d0;
wait_finished <= 1‘b0;
end
end
4‘d01 : begin
if(Busy_Tx) begin
Wrsig <= 0;
end
else begin
wait_cnt <= wait_cnt + 1;
if(wait_cnt == 12‘hA00) begin
wait_cnt <= 12‘d0;
wait_finished <= 1‘b1;
end
else if(wait_cnt == 12‘d0 && wait_finished) state <= state + 1;
end
end
4‘d02 : begin
if(!Busy_Tx) begin
Data_Tx <= data_output[64-1*8-1:64-(1+1)*8];
Wrsig <= 1;
state <= state + 1;
wait_cnt <= 12‘d0;
wait_finished <= 1‘b0;
end
end
4‘d03 : begin
if(Busy_Tx) begin
Wrsig <= 0;
end
else begin
wait_cnt <= wait_cnt + 1;
if(wait_cnt == 12‘hA00) begin
wait_cnt <= 12‘d0;
wait_finished <= 1‘b1;
end
else if(wait_cnt == 12‘d0 && wait_finished) state <= state + 1;
end
end
4‘d04 : begin
if(!Busy_Tx) begin
Data_Tx <= data_output[64-2*8-1:64-(2+1)*8];
Wrsig <= 1;
state <= state + 1;
wait_cnt <= 12‘d0;
wait_finished <= 1‘b0;
end
end
4‘d05 : begin
if(Busy_Tx) begin
Wrsig <= 0;
end
else begin
wait_cnt <= wait_cnt + 1;
if(wait_cnt == 12‘hA00) begin
wait_cnt <= 12‘d0;
wait_finished <= 1‘b1;
end
else if(wait_cnt == 12‘d0 && wait_finished) state <= state + 1;
end
end
4‘d06 : begin
if(!Busy_Tx) begin
Data_Tx <= data_output[64-3*8-1:64-(3+1)*8];
Wrsig <= 1;
state <= state + 1;
wait_cnt <= 12‘d0;
wait_finished <= 1‘b0;
end
end
4‘d07 : begin
if(Busy_Tx) begin
Wrsig <= 0;
end
else begin
wait_cnt <= wait_cnt + 1;
if(wait_cnt == 12‘hA00) begin
wait_cnt <= 12‘d0;
wait_finished <= 1‘b1;
end
else if(wait_cnt == 12‘d0 && wait_finished) state <= state + 1;
end
end
4‘d08 : begin
if(!Busy_Tx) begin
Data_Tx <= data_output[64-4*8-1:64-(4+1)*8];
Wrsig <= 1;
state <= state + 1;
wait_cnt <= 12‘d0;
wait_finished <= 1‘b0;
end
end
4‘d09 : begin
if(Busy_Tx) begin
Wrsig <= 0;
end
else begin
wait_cnt <= wait_cnt + 1;
if(wait_cnt == 12‘hA00) begin
wait_cnt <= 12‘d0;
wait_finished <= 1‘b1;
end
else if(wait_cnt == 12‘d0 && wait_finished) state <= state + 1;
end
end
4‘d10 : begin
if(!Busy_Tx) begin
Data_Tx <= data_output[64-5*8-1:64-(5+1)*8];
Wrsig <= 1;
state <= state + 1;
wait_cnt <= 12‘d0;
wait_finished <= 1‘b0;
end
end
4‘d11 : begin
if(Busy_Tx) begin
Wrsig <= 0;
end
else begin
wait_cnt <= wait_cnt + 1;
if(wait_cnt == 12‘hA00) begin
wait_cnt <= 12‘d0;
wait_finished <= 1‘b1;
end
else if(wait_cnt == 12‘d0 && wait_finished) state <= state + 1;
end
end
4‘d12 : begin
if(!Busy_Tx) begin
Data_Tx <= data_output[64-6*8-1:64-(6+1)*8];
Wrsig <= 1;
state <= state + 1;
wait_cnt <= 12‘d0;
wait_finished <= 1‘b0;
end
end
4‘d13 : begin
if(Busy_Tx) begin
Wrsig <= 0;
end
else begin
wait_cnt <= wait_cnt + 1;
if(wait_cnt == 12‘hA00) begin
wait_cnt <= 12‘d0;
wait_finished <= 1‘b1;
end
else if(wait_cnt == 12‘d0 && wait_finished) state <= state + 1;
end
end
4‘d14 : begin
if(!Busy_Tx) begin
Data_Tx <= data_output[64-7*8-1:64-(7+1)*8];
Wrsig <= 1;
state <= state + 1;
wait_cnt <= 12‘d0;
wait_finished <= 1‘b0;
end
end
4‘d15 : begin
if(Busy_Tx) begin
Wrsig <= 0;
end
else begin
wait_cnt <= wait_cnt + 1;
if(wait_cnt == 12‘hA00) begin
wait_cnt <= 12‘d0;
wait_finished <= 1‘b1;
end
else if(wait_cnt == 12‘d0 && wait_finished) begin//发送完成
finish <= 1;
busy <= 0;
end
end
end
default:;
endcase
end
end
endmodule
/* Uart时钟信号 */
module Uart_ClkDiv(
input Sys_CLK, //50Mhz系统时钟
output reg Uart_CLK //9600bps
);
reg [7:0]Uart_CLK_Cnt;
initial
begin
Uart_CLK <= 1‘b0;
Uart_CLK_Cnt <= 8‘d0;
end
always@(posedge Sys_CLK)
begin
if(Uart_CLK_Cnt <= 8‘d160)
Uart_CLK_Cnt = Uart_CLK_Cnt + 1;
else
begin
Uart_CLK = ~Uart_CLK;
Uart_CLK_Cnt = 8‘d0;
end
end
endmodule
/* Uart_Tx发送数据 */
module Uart_Tx(
input Uart_CLK,
input RST,
input [7:0] Data_Tx,//8位待发送数据
input Wrsig,
output reg Idle,//空闲状态,0表示空闲,1表示忙碌
output reg Signal_Tx//并转串,1位输出
);
//16个时钟周期发送1bit数据
reg Send;
reg WrsigBuf;
reg WrsigRise;
reg Presult;
reg [7:0]Tx_Cnt;
parameter paritymode = 1‘b0;
always@(posedge Uart_CLK) //检测写入信号的上升沿
begin
WrsigBuf <= Wrsig;
WrsigRise <= (~WrsigBuf) & Wrsig;
end
always@(posedge Uart_CLK)
begin
if(WrsigRise && (~Idle)) //当发送命令有效且线路为空闲时,启动新的数据发送进程
Send <= 1‘b1; //正在发送
else if(Tx_Cnt == 8‘d168) //除非一帧资料发送结束,否则Send信号保持高电平
Send <= 1‘b0; //正在空闲
end
always@(posedge Uart_CLK or negedge RST)
begin
if(!RST)Signal_Tx<=1‘b1;
else begin
if(Send == 1‘b1)
begin
case(Tx_Cnt) //产生起始位
8‘d0:
begin
Signal_Tx <= 1‘b0;
Idle <= 1‘b1;
Tx_Cnt <= Tx_Cnt + 8‘d1;
end
8‘d16:
begin
Signal_Tx <= Data_Tx[0]; //发送数据0位
Presult <= Data_Tx[0]^paritymode;
Idle <= 1‘b1;
Tx_Cnt <= Tx_Cnt + 8‘d1;
end
8‘d32:
begin
Signal_Tx <= Data_Tx[1]; //发送数据1位
Presult <= Data_Tx[1]^Presult;
Idle <= 1‘b1;
Tx_Cnt <= Tx_Cnt + 8‘d1;
end
8‘d48:
begin
Signal_Tx <= Data_Tx[2]; //发送数据2位
Presult <= Data_Tx[2]^Presult;
Idle <= 1‘b1;
Tx_Cnt <= Tx_Cnt + 8‘d1;
end
8‘d64:
begin
Signal_Tx <= Data_Tx[3]; //发送数据3位
Presult <= Data_Tx[3]^Presult;
Idle <= 1‘b1;
Tx_Cnt <= Tx_Cnt + 8‘d1;
end
8‘d80:
begin
Signal_Tx <= Data_Tx[4]; //发送数据4位
Presult <= Data_Tx[4]^Presult;
Idle <= 1‘b1;
Tx_Cnt <= Tx_Cnt + 8‘d1;
end
8‘d96:
begin
Signal_Tx <= Data_Tx[5]; //发送数据5位
Presult <= Data_Tx[5]^Presult;
Idle <= 1‘b1;
Tx_Cnt <= Tx_Cnt + 8‘d1;
end
8‘d112:
begin
Signal_Tx <= Data_Tx[6]; //发送数据6位
Presult <= Data_Tx[6]^Presult;
Idle <= 1‘b1;
Tx_Cnt <= Tx_Cnt + 8‘d1;
end
8‘d128:
begin
Signal_Tx <= Data_Tx[7]; //发送数据7位
Presult <= Data_Tx[7]^Presult;
Idle <= 1‘b1;
Tx_Cnt <= Tx_Cnt + 8‘d1;
end
8‘d144:
begin
Signal_Tx <= Presult; //发送奇偶校验位
Presult <= Data_Tx[0]^paritymode;
Idle <= 1‘b1;
Tx_Cnt <= Tx_Cnt + 8‘d1;
end
8‘d160:
begin
Signal_Tx <= 1‘b1; //发送停止位
Idle <= 1‘b1;
Tx_Cnt <= Tx_Cnt + 8‘d1;
end
8‘d168:
begin
Signal_Tx <= 1‘b1;
Idle <= 1‘b0; //一帧资料发送结束
Tx_Cnt <= Tx_Cnt + 8‘d1;
end
default:
Tx_Cnt <= Tx_Cnt + 8‘d1;
endcase
end
else
begin
Signal_Tx <= 1‘b1;
Tx_Cnt <= 8‘d0;
Idle <= 1‘b0;
end
end
end
endmodule
/* Uart_Rx 用于接收数据 */
module Uart_Rx(
input Uart_CLK,//采样时钟
input RST,//复位信号
input Signal_Rx,//UART数据输入
output reg [7:0] Data_Rx,//接收数据输出
output reg Rdsig,//置1时表示上层模块已经可以读8位数据了
output reg DataError_Flag,//数据出错指示
output reg FrameError_Flag//帧出错指示
);
reg [7:0]cnt;
reg RxBuf;
reg RxFall;
reg Recieve;
reg Presult;
reg Idle;
parameter paritymode = 1‘b0;
always@(posedge Uart_CLK) //检测线路的下降沿
begin
RxBuf <= Signal_Rx;
RxFall <= RxBuf & (~Signal_Rx);
end
////////////////////////////////////////////////////////////////
//启动串口接收程序
////////////////////////////////////////////////////////////////
always@(posedge Uart_CLK)
begin
if (RxFall && (~Idle)) //检测到线路的下降沿并且原先线路为空闲,启动接收数据进程
Recieve <= 1‘b1; //正在接收
else if(cnt == 8‘d170) //除非接收数据完成,否则接收状态保持
Recieve <= 1‘b0;
end
////////////////////////////////////////////////////////////////
//串口接收程序, 16个时钟接收一个bit
////////////////////////////////////////////////////////////////
always@(posedge Uart_CLK or negedge RST)
begin
if (!RST)
begin
Idle<=1‘b0;
cnt<=8‘d0;
Rdsig <= 1‘b0;
FrameError_Flag <= 1‘b0;
DataError_Flag <= 1‘b0;
Presult<=1‘b0;
Data_Rx <= 8‘b0;
end
else if(Recieve == 1‘b1)
begin
case(cnt)
8‘d0:begin
Idle <= 1‘b1;
cnt <= cnt + 8‘d1;
Rdsig <= 1‘b0;
end
8‘d24:begin //接收第0位数据
Idle <= 1‘b1;
Data_Rx[0] <= Signal_Rx;
Presult <= paritymode^Signal_Rx;
cnt <= cnt + 8‘d1;
Rdsig <= 1‘b0;
end
8‘d40:begin //接收第1位数据
Idle <= 1‘b1;
Data_Rx[1] <= Signal_Rx;
Presult <= Presult^Signal_Rx;
cnt <= cnt + 8‘d1;
Rdsig <= 1‘b0;
end
8‘d56:begin //接收第2位数据
Idle <= 1‘b1;
Data_Rx[2] <= Signal_Rx;
Presult <= Presult^Signal_Rx;
cnt <= cnt + 8‘d1;
Rdsig <= 1‘b0;
end
8‘d72:begin //接收第3位数据
Idle <= 1‘b1;
Data_Rx[3] <= Signal_Rx;
Presult <= Presult^Signal_Rx;
cnt <= cnt + 8‘d1;
Rdsig <= 1‘b0;
end
8‘d88:begin //接收第4位数据
Idle <= 1‘b1;
Data_Rx[4] <= Signal_Rx;
Presult <= Presult^Signal_Rx;
cnt <= cnt + 8‘d1;
Rdsig <= 1‘b0;
end
8‘d104:begin //接收第5位数据
Idle <= 1‘b1;
Data_Rx[5] <= Signal_Rx;
Presult <= Presult^Signal_Rx;
cnt <= cnt + 8‘d1;
Rdsig <= 1‘b0;
end
8‘d120:begin //接收第6位数据
Idle <= 1‘b1;
Data_Rx[6] <= Signal_Rx;
Presult <= Presult^Signal_Rx;
cnt <= cnt + 8‘d1;
Rdsig <= 1‘b0;
end
8‘d136:begin //接收第7位数据
Idle <= 1‘b1;
Data_Rx[7] <= Signal_Rx;
Presult <= Presult^Signal_Rx;
cnt <= cnt + 8‘d1;
Rdsig <= 1‘b0;
end
8‘d152:begin //接收奇偶校验位
Idle <= 1‘b1;
if(Presult == Signal_Rx)
DataError_Flag <= 1‘b0;
else
DataError_Flag <= 1‘b1; //如果奇偶校验位不对,表示数据出错
cnt <= cnt + 8‘d1;
Rdsig <= 1‘b0;
end
8‘d168:begin
Idle <= 1‘b1;
if(1‘b1 == Signal_Rx)
FrameError_Flag <= 1‘b0;
else
FrameError_Flag <= 1‘b1; //如果没有接收到停止位,表示帧出错
cnt <= cnt + 8‘d1;
Rdsig <= 1‘b0;
end
8‘d169:begin
Rdsig <= 1‘b1;
cnt <= cnt + 8‘d1;
end
default:
cnt <= cnt + 8‘d1;
endcase
end
else
begin
cnt <= 8‘d0;
Idle <= 1‘b0;
Rdsig <= 1‘b0;
end
end
endmodule
标签:使用 cas ram verilog route 标记 传输数据 str 警告
原文地址:https://www.cnblogs.com/kentle/p/14162415.html