rs232并行转串行的Verilog HDL设计(下)

一.设计软件使用quartus15.0,自带Modesim-Altera,设计源代码如下

module rs2321(clk,rdy,data,bps,parity,d_out);
   input clk;
	input rdy;
	input [7:0]	data;
	input [1:0]	bps;
	input parity;//0为偶校验,1为奇校验,外部输入
	output d_out;//最终串行输出口
	reg [15:0]	count;
	reg [15:0]	count_total;
	reg bps_clk;//作为波特率的输出时钟信号,0,1交替变换
	
	always@(posedge clk or posedge rdy)//波特率产生
	if(rdy)
		begin bps_clk<=0;count_total<=0;end
	else 
		if(count_total==count)
			begin count_total<=0;bps_clk<=~bps_clk;end
		else
			begin count_total<=count_total+1;end
	
	
	
	always@(posedge bps or posedge rdy)//波特率选择
		case(bps)
		   2'b00:count=1666;//9600波特率需要的计数值
		   2'b01:count=833;//19200波特率需要的计数值
	       2'b10:count=417;//38400波特率需要的计数值
	       2'b11:count=208;//76800波特率需要的计数值
		endcase
		 
		 
		 
	reg parity_mode;//校验模块
	reg p_bit;
	
	always@(data)
	parity_mode<=parity;
	
	wire event_bit;//发送方调整计算校验位的算法最后把event_bit位或者odd_bit位加到后面发送出去
	wire odd_bit;
	assign event_bit=^data;
	assign odd_bit=~event_bit;
	
	always@(parity_mode)
		if(!parity_mode)
			begin p_bit=event_bit;end//parity_mode为0设置p_bit为偶校验位,注意:但并没有说p_bit是几
		else
			begin p_bit=odd_bit;end
		  
		  
	 reg [3:0]	cnt;//cnt计数送入移位寄存器的数据位数
	 reg [10:0]	data_sent;//起始位加数据加校验位加停止位一共11位
	 reg data_out;//串行输出口,中间变量
	 reg data_out_en;
	 reg data_begin;//起始位初始值为0
	 reg data_end;//停止位初始值是1
	 initial data_begin=0;
	 initial data_end=1;
	 
	 
	always@(posedge rdy or posedge bps_clk)
		if(rdy==1)
			begin cnt<=0;data_sent<={data_end,p_bit,data[7:0],data_begin};end//数据是左移的
		else 
			if(cnt==11)//cnt是四位二进制数,11是十进制数
				begin data_out_en<=0;end
			else
				begin data_out_en<=1;data_out<=data_sent[cnt];cnt<=cnt+1;end//发送移位寄存器对应的位送出到串行口
	
	
	assign d_out=data_out_en?data_out:1'bz;//data_out_en作用就是移入一位送出一位one by one防止后面的来了前面的还没走
endmodule

二.测试激励文件代码如下:

`timescale 1 ns/ 1 ns
module rs2321_tb;
// constants                                           
// general purpose registers
//reg eachvec;
// test vector input registers
reg [1:0] bps;
reg clk;
reg [7:0] data;
reg parity;
reg rdy;
// wires                                               
wire d_out;

// assign statements (if any)                          
rs2321 i1 (
// port map - connection between master ports and signals/registers   
	.bps(bps),
	.clk(clk),
	.d_out(d_out),
	.data(data),
	.parity(parity),
	.rdy(rdy)
);

initial 
 clk = 1;
 always #31.25 clk=~clk;//隔 31.25ns,时钟反转一次,周期为 62.5ns 
 
initial 
begin     
  parity = 1;   
  bps[1:0]=2'b00;   
  data[7:0]=8'b1001_1001;       
  rdy =0 ;                                     
  #100000                                       
  rdy =1;                                      
  #100                                       
  rdy = 0;  
  #3000000  
  bps[1:0]=2'b01;  
  data[7:0]=8'b1001_0011; 
  #100000 
  rdy =1;   
  #100 
  rdy = 0;  
  #5000000  
  bps[1:0]=2'b10; 
  data[7:0]=8'b1001_1101;  
  #100000  
  rdy =1;  
  #100  
  rdy = 0;  
  #5000000 
  bps[1:0]=2'b11; 
  data[7:0]=8'b1001_0001;  
  #100000  
  rdy =1;  
  #100  
  rdy = 0;  
  #5000000
  $stop; 
end
endmodule


三.注意点总结:

   1.实体名,module的名字和.v文件名要一致

   2.实体创建工程的过程中要选择联合仿真工具modelsim-altera时,要设置为Verilog HDL语言,默 认为VHDL,否则后面仿真会出现no design loaded错误

   3 .测试激励文件编写的时候注意rdy的停顿时间,否则仿真波形无可读性

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
FPGA控制RS232串口通信实现verilog设计Quartus9.1工程源码 module ex5_rs232( clk_in,ext_rst_n, rs232_rx,rs232_tx ); input clk_in; // 25MHz主时钟 input ext_rst_n; //外部输入复位信号,低有效 input rs232_rx; // RS232接收数据信号 output rs232_tx; // RS232发送数据信号 //---------------------------------------------------- wire rst_n; //低电平复位信号 wire bps_start1,bps_start2; //接收到数据后,波特率时钟启动信号置位 wire clk_bps1,clk_bps2; // clk_bps_r高电平为接收数据位的中间采样点,同时也作为发送数据的数据改变点 wire[7:0] rx_data; //接收数据寄存器,保存直至下一个数据来到 wire rx_int; //接收数据中断信号,接收到数据期间始终为高电平 reg clk; always@(posedge clk_in) clk = ~clk; //--------------------------------------------------- //复位产生模块 sys_ctrl uut_sc( .clk(clk), .ext_rst_n(ext_rst_n), .rst_n(rst_n) ); //--------------------------------------------------- //下面的四个模块中,speed_rx和speed_tx是两个完全独立的硬件模块,可称之为逻辑复制 //(不是资源共享,和软件中的同一个子程序调用不能混为一谈) //////////////////////////////////////////// speed_select speed_rx( .clk(clk), //波特率选择模块 .rst_n(rst_n), .bps_start(bps_start1), .clk_bps(clk_bps1) ); uart_rx my_uart_rx( .clk(clk), //接收数据模块 .rst_n(rst_n), .rs232_rx(rs232_rx), .rx_data(rx_data), .rx_int(rx_int), .clk_bps(clk_bps1), .bps_start(bps_start1) ); /////////////////////////////////////////// speed_select speed_tx( .clk(clk), //波特率选择模块 .rst_n(rst_n), .bps_start(bps_start2), .clk_bps(clk_bps2) ); uart_tx my_uart_tx( .clk(clk), //发送数据模块 .rst_n(rst_n), .rx_data(rx_data), .rx_int(rx_int), .rs232_tx(rs232_tx), .clk_bps(clk_bps2), .bps_start(bps_start2) ); endmodule
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Believe Y

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值