module uartrx(clk,rst,baudset,rx,rx_done,rx_state,thedata);
input clk;
input rst;
input [2:0]baudset;
input rx;
output reg[7:0]thedata;
output reg rx_done;
output reg rx_state;
wire xjy;
reg signal1,signal2;
reg data1,data2; //服务于下降沿检测器
reg[15:0] biggest; //服务于波特率字典
reg[15:0] cnt;
reg geduan; //服务于时间隔断产生器
reg [8:0] cnt160; //服务于160隔断提取器
reg [2:0]START_BIT;
reg [2:0]STOP_BIT;
reg [2:0] regdata[7:0]; //八位数据regdata 每位数据有三位
//服务于60次采样器
//下降沿检测器:用于检测起始位那个下降沿
always@(posedge clk or negedge rst)
if(!rst)
begin
signal1 <= 1'b0;
signal2 <= 1'b0;
end
else
begin
signal1 <= rx;
signal2 <= signal1;
end
always@(posedge clk or negedge rst)
if(!rst)
begin
data1 <= 1'b0;
data2 <= 1'b0;
end
else
begin
data1 <= signal2;
data2 <= data1;
end
assign xjy = !data1 && data2;
//波特率字典,用于设置波特率,产生计数最大值
always@(posedge clk or negedge rst)
if(!rst)
biggest <= 16'd324;
else begin
case(baudset)
0:biggest <= 16'd324;
1:biggest <= 16'd162;
2:biggest <= 16'd80;
3:biggest <= 16'd53;
4:biggest <= 16'd26;
default: biggest <= 16'd324;
endcase
end
//时间隔断产生器,用于产生 (波特率计数周期÷系统周期÷16)这样的时间隔断
//当然 计算的过程已经在字典中实现了 这里只需要计数就行了
always@(posedge clk or negedge rst)
if(!rst)
cnt <= 16'b0;
else if(rx_state)begin
if(cnt == biggest)
cnt <= 16'd0;
else
cnt <= cnt + 16'd1;
end
else
cnt <= 16'd0;
always@(posedge clk or negedge rst)
if(!rst)
geduan <= 1'b0;
else if(cnt == 16'd1)
geduan <= 1'b1;
else
geduan <= 1'b0;
//隔断提取器,循环提取10*16=160个时间隔断
always@(posedge clk or negedge rst)
if(!rst)
cnt160 <= 8'd0;
else if(cnt160 == 8'd159 || (cnt160 == 8'd12 && START_BIT > 2 ))
//检验是否计满 或 出现起始位出错的情况
cnt160 <= 8'd0;
else if(geduan)
cnt160 <= cnt160 + 1'd1;
else
cnt160 <= cnt160;
//采样器 采集十位输入数据 应每位10次 共160次,但只采集稳定部分每位六次共60次
always@(posedge clk or negedge rst)
if(!rst) begin
START_BIT <= 3'd0;
regdata[0] <= 3'd0;
regdata[1] <= 3'd0;
regdata[2] <= 3'd0;
regdata[3] <= 3'd0;
regdata[4] <= 3'd0;
regdata[5] <= 3'd0;
regdata[6] <= 3'd0;
regdata[7] <= 3'd0;
STOP_BIT <= 3'd0;
end
else if(geduan)
case(cnt160)
0:begin
START_BIT <= 3'd0;
regdata[0] <= 3'd0;
regdata[1] <= 3'd0;
regdata[2] <= 3'd0;
regdata[3] <= 3'd0;
regdata[4] <= 3'd0;
regdata[5] <= 3'd0;
regdata[6] <= 3'd0;
regdata[7] <= 3'd0;
STOP_BIT <= 3'd0;
end
6,7,8,9,10,11:START_BIT <= START_BIT + signal2;
22,23,24,25,26,27:regdata[0] <= regdata[0] + signal2;
38,39,40,41,42,43:regdata[1] <= regdata[1] + signal2;
54,55,56,57,58,59:regdata[2] <= regdata[2] + signal2;
70,71,72,73,74,75:regdata[3] <= regdata[3] + signal2;
86,87,88,89,90,91:regdata[4] <= regdata[4] + signal2;
102,103,104,105,106,107:regdata[5] <= regdata[5] + signal2;
118,119,120,121,122,123:regdata[6] <= regdata[6] + signal2;
134,135,136,137,138,139:regdata[7] <= regdata[7] + signal2;
150,151,152,153,154,155:STOP_BIT <= STOP_BIT + signal2;
default:
begin
START_BIT <= START_BIT;
regdata[0] <= regdata[0];
regdata[1] <= regdata[1];
regdata[2] <= regdata[2];
regdata[3] <= regdata[3];
regdata[4] <= regdata[4];
regdata[5] <= regdata[5];
regdata[6] <= regdata[6];
regdata[7] <= regdata[7];
STOP_BIT <= STOP_BIT;
end
endcase
always@(posedge clk or negedge rst)
if(!rst)
thedata <= 8'd0;
else if(cnt160 == 8'd159)
begin
thedata[0] <= regdata[0][2]; //第0位的第2位
thedata[1] <= regdata[1][2];
thedata[2] <= regdata[2][2];
thedata[3] <= regdata[3][2];
thedata[4] <= regdata[4][2];
thedata[5] <= regdata[5][2];
thedata[6] <= regdata[6][2];
thedata[7] <= regdata[7][2];
end
//接收完成标志发生器
always@(posedge clk or negedge rst)
if(!rst)
rx_done <= 1'd0;
else if(cnt160 == 8'd159)
rx_done <= 1'd1;
else
rx_done <= 1'd0;
//接收状态跟随器:判断是否处于接收状态,并输出
always@(posedge clk or negedge rst)
if(!rst)
rx_state <= 1'b0;
else if(xjy)
rx_state <= 1'b1;
else if(rx_done || (cnt160 == 8'd12 && (START_BIT > 2)))
rx_state <= 1'b0;
else
rx_state <= rx_state;
endmodule
仿真的思路是 引入前面的串口发送模块,将发送端与接收端连接在一起,通过给发送模块的输入端写入数据,来观察接收模块的输出端的输出数据
`timescale 1ns/1ns
`define clk_period 20
module uartrx_tb;
reg[2:0] baudset;
reg[7:0] indata; //(tx的输入)
reg send_en; //(tx)
reg clk;
reg rst;
wire tx_rx;
wire tx_done;
wire uart_state;//(tx)
wire [7:0]thedata;//rx的接收
wire rx_done;
wire rx_state; //(rx)
uart uart1(
.baudset(baudset),
.indata(indata),
.send_en(send_en),
.clk(clk),
.rst(rst),
.tx(tx_rx),
.tx_done(tx_done),
.uart_state(uart_state)
);
uartrx uartrx1(
.clk(clk),
.rst(rst),
.baudset(baudset),
.rx(tx_rx),
.rx_done(rx_done),
.rx_state(rx_state),
.thedata(thedata)
);
initial clk = 1;
always#(`clk_period/2)clk = ~clk;
initial begin
rst = 1'b0;
indata = 8'd0;
send_en = 1'd0;
baudset = 3'd4;
#(`clk_period*20 + 1 );
rst = 1'b1;
#(`clk_period*50);
indata = 8'haa;
send_en = 1'd1;
#`clk_period;
send_en = 1'd0;
@(posedge tx_done)
#(`clk_period*5000);
indata = 8'h55;
send_en = 1'd1;
#`clk_period;
send_en = 1'd0;
@(posedge tx_done)
#(`clk_period*5000);
$stop;
end
endmodule
我这里出现了错误,始终我也没找到为什么没有找到设计单元 ,我明明都已经加载了
渴望得到帮助 (等好了我在回来改)