一.设计软件使用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的停顿时间,否则仿真波形无可读性