您的位置:首页 > 其它

【西西学FPGA】Lesson9 Uart

2016-05-05 13:06 357 查看
-------------------------------------------------2016年3月31日 更新-------uart_tb--------------------------------------

uart_tb的写作要点:

1 defparam// 重定义模块内部参数

2 $readmemh("num.txt",a);//系统函数

3 task调用,

4 for语句,可综合,但是浪费资源

-------------------------------------------------2016年3月31日 更新--------tx_module---------------------------------------

tx_module:收到数据和有效信号,转换成帧

1 信号列表

输入

1 sclk

2 s_rst_n

3 pi_flag 输入数据和输入时钟在同一时间传入,切输入数据有效时长1个时钟周期,当此信号为高的时候,证明这个时候传入的num为有效数据。

4 pi_num

寄存器:

tx_flag 当pi_flag有效的时候,tx_flag拉高。当bit_cnt == 9 bit_flag = 1 拉低,即 数据传输完成

baut_cnt 当 tx_flag 拉高,开始计数,满5208 则清零重新计数

bit_cnt 每发送一个数据,加一

bit_flag 计数器baut_cnt 满 5208的时候,拉高一个周期

num_tmp 对输入数据的缓存

输出

5 po_tx 单位输出,为帧类型

/****************************************************************************************************************

module tx_module(

input wire sclk ,

inout wire s_rst_n ,

input wire pi_flag ,

input wire [7:0] pi_num,

output reg po_tx

);

reg [20:0] baut_cnt;

reg [3:0] bit_cnt;

reg bit_flag;

reg tx_flag;//输入数据开始,就拉高信号,当信号输出完成,则信号拉低

reg [7:0] num_tmp;//输入数据缓存

parameter

BIT_CNT = 4'd9,

BIT_RESET = 4'd0,

BAUT_CNT = 21'd5028,

BAUT_RESET = 21'd0;

//num_tmp √

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

num_tmp <= 8'b0;

else if(pi_flag == 1'b1)

num_tmp <= pi_num;

//po_tx

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

po_tx <= 1'b1;

else if(pi_flag == 1'b1)

po_tx <= 1'b0;

else if(bit_flag == 1'b1)

begin

if(bit_cnt == 4'd0) po_tx <= num_tmp[0];

if(bit_cnt == 4'd1) po_tx <= num_tmp[1];

if(bit_cnt == 4'd2) po_tx <= num_tmp[2];

if(bit_cnt == 4'd3) po_tx <= num_tmp[3];

if(bit_cnt == 4'd4) po_tx <= num_tmp[4];

if(bit_cnt == 4'd5) po_tx <= num_tmp[5];

if(bit_cnt == 4'd6) po_tx <= num_tmp[6];

if(bit_cnt == 4'd7) po_tx <= num_tmp[7];

if(bit_cnt == 4'd8) po_tx <= 1'b1;

end

//tx_flag

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

tx_flag <= 1'b0;

else if ((bit_cnt == BIT_CNT )&&(bit_flag == 1'b1))

tx_flag <= 1'b0;

else if(pi_flag == 1'b1)

tx_flag <= 1'b1;

//baut_cnt

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

baut_cnt <= BAUT_RESET;

else if((baut_cnt == BAUT_CNT)||((bit_cnt == BIT_CNT )&&(bit_flag == 1'b1)))

baut_cnt <= BAUT_RESET;

else if(tx_flag == 1'b1)

baut_cnt <= baut_cnt + 1'b1;

//bit-cnt

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

bit_cnt <= BIT_RESET;

else if((bit_cnt == BIT_CNT )&&(bit_flag == 1'b1))

bit_cnt <= BIT_RESET;

else if (bit_flag == 1'b1)

bit_cnt <= bit_cnt + 1'b1;

//bit_flag

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

bit_flag <= 1'b0;

else if (baut_cnt == BAUT_CNT)

bit_flag <= 1'b1;

else

bit_flag <= 1'b0;

endmodule

****************************************************************************************************************/

-------------------------------------------------2016年3月31日 更新---------rx_module--------------------------------------

发现需要将笔记思路记录下来,否则都忘记自己当时写代码的思路了。还要养成写文档的好习惯

rx_module 收到帧,转换为8bit的数据

1 信号列表:

输入信号列表

1 sclk 系统时钟

2 s_rst_n 系统复位

3 rx 输入信号,为帧

内部寄存器列表

1 rx_tmp 对输入rx做一个时钟延时

2 rx_flag 当rx_tmp和rx不一致,则拉高。当帧数据传输完成则拉低

3 baut_cnt 保证一位数据宽度满足波特率9600;参数值为5208;

4 bit_flag 在baut_cnt 为 BAUT_CNT 一半的时候,将收到的数据传输给缓存

5 bit_cnt 收到一个数据,缓存一位的数值

输出信号列表

6 po_rx_flag 当接收完成的时候,输出一个时间单位的高电平,同时输出数据。当做输出数据有效的标志位

7 po_rx_data

/****************************************************************************************************************

module rx_module(

input wire sclk ,

input wire s_rst_n ,

input wire rx_data_in ,

output reg [7:0] po_rx_data ,

output reg po_rx_flag

);

reg rx_flag;//波形一来,就拉高。

reg [20:0] baut_cnt;//计数到5208 对应的波特率为9600

reg bit_flag;//在计数到BAUT_CNT一半的时候拉高

reg [3:0] bit_cnt; //flag每为1 ,则bit_cnt 加1

reg [7:0] rx_data_tmp;//当bit_flag 为1 ,的时候,去当前值赋值

reg rx_data_delay1,rx_data_delay2;//将输入数据延迟两个周期,消除亚稳态 √

//

parameter

BIT_CNT = 4'd9,

BIT_RESET = 4'd0,

BAUT_CNT = 21'd5208,

BAUT_HALF = 21'd2604,

BAUT_RESET = 21'd0;

//rx_data_delay1,rx_data_delay2;√

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

rx_data_delay1 <= 1'b0;

else

rx_data_delay1 <= rx_data_in;

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

rx_data_delay2 <= 1'b0;

else

rx_data_delay2 <= rx_data_delay1;

//po_rx_data,

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

po_rx_data <= 8'd0;

else if((bit_cnt == BIT_CNT)&&(bit_flag == 1'b1 ))

po_rx_data <= rx_data_tmp;

//po_rx_flag

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

po_rx_flag <= 1'b0;

else if((bit_cnt == BIT_CNT)&&(bit_flag == 1'b1 ))

po_rx_flag <= 1'b1;

else

po_rx_flag <= 1'b0;

//rx_flag;

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

rx_flag <= 1'b0;

else if ((bit_flag == 1'b1)&&(bit_cnt ==BIT_CNT))

rx_flag <= 1'b0;

else if((rx_data_delay1 == 1'b0)&&(rx_data_delay2 == 1'b1))

rx_flag <= 1'b1;

//baut_cnt;

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

baut_cnt <= BAUT_RESET;

else if((baut_cnt == BAUT_CNT)||((bit_cnt == BIT_CNT)&&(bit_flag == 1'b1 )))

baut_cnt <= BAUT_RESET;

else if(rx_flag == 1'b1)

baut_cnt <= baut_cnt + 1'd1;

//bit_flag;

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

bit_flag <= 1'b0;

else if((bit_cnt == BIT_CNT)&&(bit_flag == 1'b1 ))

bit_flag<= 1'b0;

else if(baut_cnt == BAUT_HALF)

bit_flag <= 1'b1;

else

bit_flag <= 1'b0;

//bit_cnt;

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

bit_cnt <= BIT_RESET;

else if((bit_flag == 1'b1)&&(bit_cnt ==BIT_CNT))

bit_cnt <= BIT_RESET;

else if(bit_flag == 1'b1)

bit_cnt <= bit_cnt + 1'b1;

//rx_data_tmp

always@(posedge sclk or negedge s_rst_n)

if(!s_rst_n)

rx_data_tmp <= 8'b0;

else

begin

if((bit_flag == 1'b1)&&(bit_cnt == 4'd1)) rx_data_tmp[0] <= rx_data_delay2;

if((bit_flag == 1'b1)&&(bit_cnt == 4'd2)) rx_data_tmp[1] <= rx_data_delay2;

if((bit_flag == 1'b1)&&(bit_cnt == 4'd3)) rx_data_tmp[2] <= rx_data_delay2;

if((bit_flag == 1'b1)&&(bit_cnt == 4'd4)) rx_data_tmp[3] <= rx_data_delay2;

if((bit_flag == 1'b1)&&(bit_cnt == 4'd5)) rx_data_tmp[4] <= rx_data_delay2;

if((bit_flag == 1'b1)&&(bit_cnt == 4'd6)) rx_data_tmp[5] <= rx_data_delay2;

if((bit_flag == 1'b1)&&(bit_cnt == 4'd7)) rx_data_tmp[6] <= rx_data_delay2;

if((bit_flag == 1'b1)&&(bit_cnt == 4'd8)) rx_data_tmp[7] <= rx_data_delay2;

end

endmodule

****************************************************************************************************************/

--------------------------------------------------2016年3月27日 杨亮------------------------------------------------------------

1 tx_rx

2 task 调用

3 波特率和比特率

4 $readmemh(“filename”, mem_name)在使用这个命令时,”filename”中的路径要用反斜杠’/’,而不是斜杠’\’。

5 for 语句

for 属于可综合语句,但是每执行一个语句,就会有一个电路的产生,容易造成资源浪费。

6 采样率 载波

载波 或者载频(载波频率)是一个物理概念,其实就是一个特定频率的无线电波,单位Hz。在无线通信技术上我们使用载波传递信息,将数字信号调制到一个高频载波上然后再在空中发射和接收。所以载波是传送信息(话音和数据)的物理基础,最终的承载工具。形象的说载波就是一列火车,用户的信息就是货物。

7

关于 uart_tb的写法

1 定义一个写了数字的 .txt文件

2 代码:

/**************************************************************************************************************************************************************************************************************************************************************************************************************************************************

/**************************************************************************************************************************************************************************************************************************************************************************************************************************************************

module uart_tb;

reg sclk;

reg s_rst_n;

reg rx;

reg [7:0] a[255:0];

wire tx;

defparam uart_inst.tx_module1.BAUT_CNT = 52;

defparam uart_inst.rx_module1.BAUT_CNT = 52;

initial

begin

$readmemh("num.txt",a);

sclk = 1;

s_rst_n = 0;

#30 s_rst_n = 1;

end

always #5 sclk = ~sclk;

initial

begin

rx <= 1'b1;

#200 rx_byte();

end

task rx_byte();

integer j;

for(j=0;j<10;j=j+1)

rx_bit(a[j]);

endtask

task rx_bit(input [7:0]data);//把数字转化为 rx帧

integer i;

for (i = 0;i < 10;i = i+1)

begin

case(i)

0:rx <= 1'b0;

1:rx <= data[0];

2:rx <= data[1];

3:rx <= data[2];

4:rx <= data[3];

5:rx <= data[4];

6:rx <= data[5];

7:rx <= data[6];

8:rx <= data[7];

9:rx <= 1'b1;

endcase

#520;

end

endtask

uart uart_inst(

.sclk (sclk ),

.s_rst_n (s_rst_n ) ,

.rx_data_in(rx) ,

.po_tx(tx)

);

endmodule

/**************************************************************************************************************************************************************************************************************************************************************************************************************************************************/**************************************************************************************************************************************************************************************************************************************************************************************************************************************************/***************************************************************************************************************************************************************************************************************************************************************************************************************************************************/

作业:

2 精简帧协议
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: