文章目录
八、分频器(2的偶数分频、16分频(占空比为2:14)、5分频)
一、4位半加法器的实现
- 半加器: 加数和被加数为输入,sum与进位为输出。
- 全加器: 加数、被加数与低位的进位数为输入,sum与进位为输出
四位半加器:输入为四位加数、四位被加数, 输出为四位和数、1位进位。
比如:
- 1000+0000=0 1000, 输出“和数为1000、进位为0”
- 1000+1000=1 0000, 输出“和数为0000、进位为1”
1、系统框图:
2、Verilog代码
- add4_half.v(源文件)
module add4_half(a,b,sum,cout);
input [3:0] a,b; //a、b<--输入
output [3:0] sum; //sum-->输出变量
output cout; //cout-->输出变量
assign {cout,sum}=a+b; //a+b,进位保存至cout,和数保存至sum
endmodule
- tb_add4_half.v(testbench仿真文件)
`timescale 1us/1ps //Time Delay Unit is 1us
module tb_add4_half();
reg [3:0] A,B; //Two input registers
// wire sum; //sum --> set as one wire ,for sum is operated by assign statement
// wire cout; //cout -->set as one wire ,for cout is operated by assign statement
parameter delay = 5000; //delayTime's numbers, delayTime=5ms
add4_half Instance(
.a(A),
.b(B)
);//Mappings and instantiation
/* Initializing Input Signals */
initial
begin
/*Five sets of examples*/
A=4'b0101; B=4'b1010; // Group 1 its result should be "sum=1111=15,cout=0" >5+10=15 overflow bit = 0
#delay A=4'b0001; B=4'b0001; // Group 2 its result should be "sum=0010=2,cout=0" >1+1=2 overflow bit = 0
#delay A=4'b1000; B=4'b1000; // Group 3 its result should be "sum=0000=0,cout=1" >8+8=15+1 overflow bit = 1
#delay A=4'b1010; B=4'b1001; // Group 4 its result should be "sum=0011=3,cout=1" >10+9=15+4 overflow bit = 1
#delay A=4'b1111; B=4'b1111; // Group 5 its result should be "sum=1110=14,cout=1" >15+14=15+14 overflow bit = 1
#delay; //if u don't write down this delay statement, the last result will be invisible.
end
endmodule
3、仿真结果
二、138译码器的Verilog实现
1、系统框图
2、Verilog代码
- decode_138.v(源文件)
module decode_138(A, Y_n);
input [2:0] A;
output reg[7:0] Y_n;
always @(A)
begin
case(A)
3'b000: Y_n=8'b1111_1110 ; //0---Y_0
3'b001: Y_n=8'b1111_1101 ; //1---Y_1
3'b010: Y_n=8'b1111_1011 ; //2---Y_2
3'b011: Y_n=8'b1111_0111 ; //3---Y_3
3'b100: Y_n=8'b1110_1111 ; //4---Y_4
3'b101: Y_n=8'b1101_1111 ; //5---Y_5
3'b110: Y_n=8'b1011_1111 ; //6---Y_6
3'b111: Y_n=8'b0111_1111 ; //7---Y_7
endcase
end
endmodule
- tb_decode_138.v(testbench仿真文件)
`timescale 1us/1ps //延时单位为1us,精度为1ps
module tb_decode_138();
reg [2:0] A;
parameter delay=5; //每产生一个结果,延时5us
//例化
decode_138 instance1(
.A(A)
);
//初始化赋值5组样例
initial
begin
A=3'd1; //1-->第2个灯亮(从右往左,低电平)
#delay
A=3'd3; //3-->第4个灯亮(从右往左,低电平)
#delay
A=3'd7; //7-->第8个灯亮(从右往左,低电平)
#delay
A=3'd5; //5-->第6个灯亮(从右往左,低电平)
#delay
A=3'd0; //0-->第1个灯亮(从右往左,低电平)
#delay;
end
endmodule
3、仿真结果
三、并行输入串行输出移位寄存器
1、系统框图
2、Verilog代码
- shift_4t1.v(源文件)
/*移位寄存器--并行输入串行输出(4-->1) 同步加载、移位*/
module shift_4t1(clk, din, load, q);
input clk, load;
input [3:0] din;
output reg q;
reg [3:0] tmp;
always@(posedge clk)
begin
if(load==1'b1) //上升沿到来且满足load=1时,将din值加载到tmp
tmp <= din;
else //上升沿到来且满足load=1时,将tmp向左移位
//begin循环移位
begin //tmp=1
tmp <= tmp<<1;
tmp[0] <= 1'b0;
q <= tmp[3]; //此处q等于前一个上升沿的tmp[3],而不是tmp<<1后的tmp
end
end
endmodule
- tb_shift_4t1.v(testbench仿真文件)
`timescale 10ns/1ps //Time Delay Unit is 10ns
module tb_shift_4t1();
reg CLK, LOAD; //Three input registers
reg [3:0] DIN;
//wire Q; //Q --> set Q as one wire
parameter clkCircle = 10; //clkCircle's numbers, clkCircle=10ns
parameter delay = 80; //delayTime's numbers, delayTime=0.8us
shift_4t1 Instance(
.clk(CLK),
.load(LOAD),
.din(DIN)
);//Mappings and instantiation
/*CLK*/
initial
begin
CLK=0;
forever
#(clkCircle/2) CLK = ~ CLK; //Flip the level state of CLK every half cycle
end
/* Initializing Input Signals */
initial
begin
DIN=4'b0001;
LOAD = 1; //Load the first DIN(tmp of DIN is updated)
@(posedge CLK); //Waiting for posedge clock "CLK"
LOAD = 0; //tmp of DIN is beginning shifting left and ouput Q
#delay; //Delay some time, awaiting before Next DIN's loading
DIN=4'b0111;
LOAD = 1; //Load the first DIN(tmp of DIN is updated)
@(posedge CLK); //Waiting for posedge clock "CLK"
LOAD = 0; //tmp of DIN is beginning shifting left and ouput Q
#delay; //Delay some time, awaiting before Next DIN's loading
DIN=4'b1010;
LOAD = 1; //Load the first DIN(tmp of DIN is updated)
@(posedge CLK); //Waiting for posedge clock "CLK"
LOAD = 0; //tmp of DIN is beginning shifting left and ouput Q
#delay; //Delay some time, awaiting before Next DIN's loading
DIN=4'b1101;
LOAD = 1; //load the first DIN(tmp of DIN is updated)
@(posedge CLK); //waiting for posedge clock "CLK"
LOAD = 0;
#delay; //delay some time, awaiting before Next DIN's loading
DIN=4'b1111;
LOAD = 1;
@(posedge CLK); //waiting for posedge clock "CLK"
LOAD = 0;
#delay; //Delay some time, awaiting before Next DIN's loading
DIN=4'b0101;
LOAD = 1;
@(posedge CLK); //waiting for posedge clock "CLK"
LOAD = 0;
#delay; //delay some time, awaiting before Next DIN's loading
end
endmodule
3、仿真结果
四、带异步复位和置位、上升沿触发的触发器
1、系统框图
2、Verilog代码
- dff_asynrst.v(源文件)
module dff_asynrst(data,rst,set,clk,q);
input data,rst,set,clk;
output reg q;
always@(posedge clk or posedge rst or posedge set) //三个异步时钟信号
begin
if(rst==1'b1) //如果复位信号来到,将q置0
q <= 1'b0;
else if(set==1'b1) //如果置位信号来到,将q置1
q <= 1'b1;
else
q<=data; //否则,将data值赋值给q
end
endmodule
- tb_dff_asynrst.v(testbench仿真文件)
module
3、仿真结果
五、模10计数器
1、系统框图
2、Verilog代码
- counter10.v(源文件)
//模10计数器的Verilog HDL设计
module counter10(clk, rst_n, en, dout, co);
input clk, rst_n, en;
output[3:0] dout;
reg [3:0] dout;
output co;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
dout <= 4'b0000; //系统复位,计数器清零
else if(en)
if(dout == 4'b1001) //计数值达到5时,计数器清零
dout <= 4'b0000;
else
dout <= dout + 1'b1; //否则,计数器加1
else
dout <= dout;
end
assign co = dout[0]&dout[3]; //当计数达到5(4'b1001)时,进位为1,计数值为其他,都没有进位
endmodule
- tb_counter10.v(testbench仿真文件)
module
3、仿真结果
六、停车场剩余车位计数显示牌的Verilog实现
1、系统框图
2、Verilog代码
- parkinglot.v(源文件)
module parkinglot(in, out, remain,num_1,num_0,led_1,led_0);
input in, out;
output reg [4:0] remain;
output reg [3:0] num_1,num_0;
output reg [6:0] led_1, led_0;
integer i;
initial //初始化
begin
remain = 5'b11000; //初始赋值为24
end
always@(in or out) //main_module,计数器处理
begin
if(in == 1'b1 && remain>0)
begin
remain <= remain - 1'b1;
end
if(out == 1'b1 && remain<24)
begin
remain <= remain + 1'b1;
end
end
always@(remain) //将剩余车位数量转换成BCD码,并将个位数、十位数保存至num_0、num_1
begin
num_1=4'd0;
num_0=4'd0;
for(i=4;i>=0;i=i-1)
begin
if(num_1>=5)
num_1=num_1+3;
if(num_0>=5)
num_0=num_0+3;
num_1 = num_1<<1;
num_1[0] = num_0[3];
num_0 = num_0<<1;
num_0[0]= remain[i];
end
end
always@(num_0) //将一条5位的remain总线转换成2条7位的led总线(供显示模块调用以显示)
begin
case(num_0)
5'd0: led_0<=7'b011_1111;
5'd1: led_0<=7'b000_0110;
5'd2: led_0<=7'b101_1011;
5'd3: led_0<=7'b100_1111;
5'd4: led_0<=7'b110_0110;
5'd5: led_0<=7'b110_1101;
5'd6: led_0<=7'b111_1100;
5'd7: led_0<=7'b000_0111;
5'd8: led_0<=7'b111_1111;
5'd9: led_0<=7'b110_0111;
default: led_0<=7'b000_0000;
endcase
case(num_1)
5'd0: led_1<=7'b011_1111;
5'd1: led_1<=7'b000_0110;
5'd2: led_1<=7'b101_1011;
default: led_1<=7'b000_0000;
endcase
end
endmodule
- tb_parkinglot.v(testbench仿真文件)
`timescale 1us/1ps //Time Delay Unit is 1us
module tb_parkinglot();sim:/tb_parkinglot/OUT sim:/tb_parkinglot/IN sim:/tb_parkinglot/Instance
reg IN, OUT; //Two input registers
parkinglot Instance(
.in(IN),
.out(OUT)
);//Mappings and instantiation
/* Initializing Input Signals */
initial
begin
IN=0;
OUT=0;
end
initial
begin
#10 IN=1;OUT=0;
#10 OUT=1;IN=0;
#10 IN=1;OUT=0;
#20 OUT=1;IN=0;
#2 IN=1;OUT=0;
#15 OUT=1;IN=0;
#1 OUT=1;IN=0;
#30 IN=1;OUT=0;
#3 IN=1;
#1 OUT=1;
#3 IN=1;
#1 OUT=1;
#20 IN=1;
#5 OUT=1;
#20;
end
endmodule
3、仿真结果
七、银行排号机系统电路
1、系统框图
2、Verilog代码
- BankQueue.v(源文件)
module BankQueue(N, V, key1, key2, key3, led1, led2, led3);
input N, V, key1, key2, key3;
output led1, led2, led3;
reg [7:0] led1, led2, led3;
reg [7:0] vw=8'b0000_0000, nw=8'b0000_0000;
reg [7:0] cntn=8'b0000_0000, cntv=8'b1100_1000; //排号机普通客户计数器、VIP客户计数器
reg [7:0] cntnormal=8'b0000_0000, cntvip=8'b1100_1000; //柜台的普通客户、VIP客户计数器
always@( N or V ) //异步时序,电平触发
begin
if(V == 1'b1 && cntv+cntn < 8'd500)
cntv = cntv + 8'd1;
if(N== 1'b1 && cntv+cntn < 8'd500)
cntn = cntn+ 8'd1;
end
always@ (cntv or cntvip or cntn or cntnormal) //VIP竞争机制
begin
vw = cntv - cntvip; //柜台VIP计数器的号数 - 排号机VIP计数器的号数才可以接下一个客户
nw = cntn - cntnormal;
end
always@ (key1 or key2 or key3) //异步时序,电平触发
begin
if(key1 == 1'b1) //当key1按下时
if(vw > 0) //若VIP客户抢得
begin
cntvip = cntvip + 1;
led1 = cntvip; //显示正在处理的号数
end
else if(nw > 0)
begin
cntnormal = cntnormal + 1;
led1 = cntnormal; //显示正在处理的号数
end
if(key2 == 1'b1)
if(vw > 0)
begin
cntvip = cntvip + 1;
led2 = cntvip; //显示正在处理的号数
end
else if(nw > 0)
begin
cntnormal = cntnormal + 1;
led2 = cntnormal; //显示正在处理的号数
end
if(key3 == 1'b1)
if(vw > 0)
begin
cntvip = cntvip + 1;
led3 = cntvip; //显示正在处理的号数
end
else if(nw > 0)
begin
cntnormal = cntnormal + 1;
led3 = cntnormal; //显示正在处理的号数
end
end
endmodule
- tb_BankQueue.v(testbench仿真文件)
`timescale 1ns/1ps
module tb_BankQueue();
reg N, V, Key1, Key2, Key3;
BankQueue Test(.N(N),.V(V),.key1(Key1),.key2(Key2),.key3(Key3));
initial //Initiating
begin
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
end
initial //Process
begin
#1
N=1;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#3
N=1;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=1;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#2
N=1;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=1;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=1;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=1;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=1;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#3
N=0;
V=0;
Key1=1;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=1; //
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=1; //
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=1;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=1;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=1;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=1;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=1;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=1;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=1;
#1
N=0;
V=0;
Key1=0;
Key2=0;
Key3=0;
#1
N=1; //
V=1; //
Key1=1;
Key2=0;
Key3=0;
#1;
end
endmodule
3、仿真结果
八、分频器(2的偶数分频、16分频(占空比为2:14)、5分频)
① 2的整数次幂的偶数分频器——2、4、8、16分频器
-
系统框图
-
Verilog代码
1、freq_div.v(源文件)
/*2的整数次幂偶数分频器:2、4、8、16分频器*/
module freq_div(clk,rst,clk2,clk4,clk8,clk16);
input rst,clk;
output clk2,clk4,clk8,clk16;
wire clk2,clk4,clk8,clk16; //用"assign"语句赋值的变量,需定义为wire型
reg [3:0] cnt;
always@(posedge clk or posedge rst) //上升沿触发,只有复位才会重置为零的计数器
begin
if(rst==1'b1)
cnt <= 4'b0000;
else
cnt <= cnt+1;
end
assign clk2 = cnt[0]; //取出计数变量cnt的相应位的0、1状态作为本身的0、1状态
assign clk4 = cnt[1];
assign clk8 = cnt[2];
assign clk16 = cnt[3];
endmodule
2、 tb_freq_div.v(testbench仿真文件)
module
3、仿真结果
② 占空比为2:14的16分频器
-
系统框图
-
Verilog代码
1、freq_div.v(源文件)
/*占空比不为50%的分频器————2:14占空比16分频器*/
module freq_div(clk,rst, clk2_14);
input clk,rst;
output reg clk2_14;
reg [3:0] cnt;
always@(posedge clk or posedge rst) //上升沿触发,只有复位才会重置为零的计数器
begin
if(rst == 1'b1)
cnt <=4'b0000; //重置计数变量cnt为0
else
cnt <= cnt + 1;
end
always@(posedge clk or posedge rst)
begin
if(rst == 1'b1)
clk2_14 <= 1'b0; //rst重置clk2_14为0(低电平)
else if(cnt ==13 || cnt == 14)
clk2_14 <= 1'b1; //当rst==0、上升沿到来,且cnt已经计数到13或14时,将clk2_14置为1(高电平)
else
clk2_14=1'b0; //当rst==0、上升沿到来,且cnt没有计数到13、14,clk2_14置为0(低电平)
end
endmodule
2、 tb_freq_div.v(testbench仿真文件)
module
3、仿真结果
③ 奇数分频器——5分频器
-
系统框图
-
Verilog代码
1、freq_div.v(源文件)
/*奇数分频器——5分频器*/
module freq_div(clk, rst, clk_5);
input clk, rst;
output clk_5;
wire clk_5; //用"assign"语句赋值的变量,需定义为wire型
reg [2:0] cnt_pre, cnt_later;
reg clk_5_pre, clk_5_later;
always@(posedge clk or posedge rst) // 上升沿触发,5进制计数器。范围:000、001、010、011、100
if(rst == 1)
cnt_pre <= 3'b000;
else if(cnt_pre == 3'b100) // 000 001 010 011 100 --> 000 001 010 011 100 --> 001 010 011 100 --> ···
cnt_pre <= 3'b000;
else
cnt_pre <= cnt_pre + 1;
always@(posedge clk or posedge rst) //上升沿触发,占空比为2:3的分频器
if(rst == 1)
clk_5_pre <= 0;
else if(cnt_pre == 3'b000 || cnt_pre == 3'b100) // 在上升沿到来时,计数到000或100之后这样判断为1,才会置为1(高电平)
clk_5_pre <= 1;
else
clk_5_pre =0;
always@(negedge clk or posedge rst) // 下降沿触发,5进制计数器。范围:000、001、010、011、100
if(rst == 1)
cnt_later <= 3'b000;
else if(cnt_later == 3'b100) // 000 001 010 011 100 --> 000 001 010 011 100 --> 001 010 011 100 --> ···
cnt_later <= 3'b000;
else
cnt_later <= cnt_later + 1;
always@(negedge clk or posedge rst) //下降沿触发,占空比为2:3的分频器
if(rst == 1)
clk_5_later <= 0;
else if(cnt_later == 3'b000 || cnt_later == 3'b100) // 在下降沿到来时,计数到000或100之后这样判断为1,才会置为1(高电平)
clk_5_later <= 1;
else
clk_5_later =0;
assign clk_5 = clk_5_pre | clk_5_later;
endmodule
tb_freq_div.v(testbench仿真文件)
module
3、仿真结果
九、四选一数据选择器——testbench仿真
1、系统框图
2、Verilog代码
- t1.v(源文件)
module t1(a,b,c,d,s1,s0,y);
input a,b,c,d;
input s0,s1;
output y;
reg y=0; //这里要赋初值,不然仿真时就看不到y的输出结果了
always@(a,b,c,d,s1,s0)
begin
case({s1,s0})
2'b00: y<=a; // s1_s0 = 00时,y=a(这里的下划线指s1和s0间的拼接符)
2'b01: y<=b; // s1_s0 = 01时,y=b
2'b10: y<=c; // s1_s0 = 10时,y=c
2'b11: y<=d; // s1_s0 = 11时,y=d
default: y<=a; // 其他情况,y=a
endcase
end
endmodule
- tb_t1.v(testbench仿真文件)
`timescale 1ns/1ps
module tb_t1();
reg va,vb,vc,vd,s1,s0;
t1 T1(.a(va),.b(vb),.c(vc),.d(vd),.s1(s1),.s0(s0));
initial
begin
va=0;
vb=1;
vc=0;
vd=1;
end
initial
begin
s1=0;
#10 s1=1;
#1 s1=0;
#15 s1=1;
#1 s1=0;
#20 s1=1;
#1 s1=0;
#10 s1=1;
#1 s1=0;
#30 s1=1;
#1 s1=0;
end
initial
begin
s0=0;
#18 s0=1;
#1 s0=0;
#8 s0=1;
#1 s0=0;
#30 s0=1;
#1 s0=0;
#40 s0=1;
#1 s0=0;
end
endmodule
3、仿真结果
十、ASK调制、FSK调制(正弦波)
1)ASK调制(键控法)
① 系统框图
② Verilog代码
- ASK_modulate.v(源文件)
module ASK_modulate(clk, start, x, y);
input clk;
input start; //开始调制的信号
input x; //基带信号(调制前的信号)
output y; //调制后的信号
wire y;
reg [1:0] q; //分频计数器
reg f; //载波信号
always @(posedge clk)
begin
if(start == 0)
q <= 0 ;
else if(q <= 1) //
begin
f <= 1;
q <= q + 1;
end
else if(q==3) //
begin
f <= 0;
q <= 0;
end
else //
begin
f <= 0;
q <= q + 1;
end
end
assign y = x && f; //对基带信号进行调制
endmodule
- tb_ASK_modulate.v(testbench仿真文件)
`timescale 100ns/1ps //延时间隔单位为0.1us
module TB_ASK_Modulate();
reg CLK, START, X;
//parameter initTime = 30;
parameter period = 2;
ASK_modulate Obj(.clk(CLK), .start(START), .x(X));
/*时钟脉冲信号,占空比为50%,周期为period=0.2us*/
initial
begin
CLK = 0;
//#initTime;
forever
#(period/2) CLK = ~CLK;
end
/*同步启动信号,CLK的第一个下降沿到来后开始ASK调制*/
initial
begin
START=0;
@(posedge CLK);
START=1;
end
/*基带信号*/
initial
begin
X=0;
#50 X=1; // 1持续5us
#50 X=0; // 0持续5us
#50 X=1; // 1持续10us
#100 X=0; // 0持续10us
#100 X=1; // 1持续5us
#50 X=0; // 0持续10us
#100 X=1; // 1持续5us
#50 X=0; // 0持续不变
end
endmodule
③ 仿真结果
1)FSK调制(正弦波模拟)
① 系统框图
② Verilog代码
- FSK_modulate_mini.v(源文件)
module FSK_modulate_mini(
input clk,//时钟信号
output reg [7:0]sigOut,//输出已调信号
output reg [7:0]carryWave1,//1对应的载波幅度
output reg [7:0]carryWave0,//0对应的载波幅度
output wire codeSource,//数字基带信号
output reg codeClk=0,//用来控制数字基带信号的时钟
output reg stClk=0//用来控制载波的时钟,数字基带时钟周期应为载波时钟的n倍
);
//分频器部分
reg [7:0]codeClkCount=0;//时钟计数器
reg [3:0]carryClkCount=0;//载波时钟计数器
always @(posedge clk)
begin
//codeClk
if(codeClkCount==127)
begin
codeClk=~codeClk;
codeClkCount=0;
end
else
begin
codeClkCount=codeClkCount+1;
end
//carryClk
if(carryClkCount==1)
begin
stClk=~stClk;
carryClkCount=0;
end
else
begin
carryClkCount=carryClkCount+1;
end
end
//数字基带信号,m序列发生器
reg [5:0]outReg=6'b010101;//序列寄存器初始化
reg mAdded;//m序列移位的辅助变量
assign codeSource=outReg[5];//输出变量为寄存器序列的最高位
always @(negedge codeClk)
begin
//手动异或
if(outReg[0]==outReg[5])
begin
mAdded=0;
end
else
begin
mAdded=1;
end
outReg=outReg<<1;//对寄存器左移
outReg=outReg+mAdded;
end
//载波的产生
reg [7:0]waveCount=0;//载波幅度查询变量
always @(posedge stClk)
begin
if(waveCount==63)
begin
waveCount=0;
end
else
begin
waveCount=waveCount+1;
end
//根据查询变量进行载波幅度查询
case(waveCount)
0: begin carryWave0<=0;carryWave1<=0; end
1: begin carryWave0<=12;carryWave1<=25; end
2: begin carryWave0<=25;carryWave1<=49; end
3: begin carryWave0<=37;carryWave1<=71; end
4: begin carryWave0<=49;carryWave1<=90; end
5: begin carryWave0<=60;carryWave1<=106; end
6: begin carryWave0<=71;carryWave1<=117; end
7: begin carryWave0<=81;carryWave1<=125; end
8: begin carryWave0<=90;carryWave1<=127; end
9: begin carryWave0<=98;carryWave1<=125; end
10:begin carryWave0<=106;carryWave1<=117; end
11:begin carryWave0<=112;carryWave1<=106; end
12:begin carryWave0<=117;carryWave1<=90; end
13:begin carryWave0<=122;carryWave1<=71; end
14:begin carryWave0<=125;carryWave1<=49; end
15:begin carryWave0<=126;carryWave1<=25; end
16:begin carryWave0<=127;carryWave1<=0; end
17:begin carryWave0<=126;carryWave1<=-25; end
18:begin carryWave0<=125;carryWave1<=-49; end
19:begin carryWave0<=122;carryWave1<=-71; end
20:begin carryWave0<=117;carryWave1<=-90; end
21:begin carryWave0<=112;carryWave1<=-106; end
22:begin carryWave0<=106;carryWave1<=-117; end
23:begin carryWave0<=98;carryWave1<=-125; end
24:begin carryWave0<=90;carryWave1<=-127; end
25:begin carryWave0<=81;carryWave1<=-125; end
26:begin carryWave0<=71;carryWave1<=-117; end
27:begin carryWave0<=60;carryWave1<=-106; end
28:begin carryWave0<=49;carryWave1<=-90; end
29:begin carryWave0<=37;carryWave1<=-71; end
30:begin carryWave0<=25;carryWave1<=-49; end
31:begin carryWave0<=12;carryWave1<=-25; end
32:begin carryWave0<=0;carryWave1<=0; end
33:begin carryWave0<=-12;carryWave1<=25; end
34:begin carryWave0<=-25;carryWave1<=49; end
35:begin carryWave0<=-37;carryWave1<=71; end
36:begin carryWave0<=-49;carryWave1<=90; end
37:begin carryWave0<=-60;carryWave1<=106; end
38:begin carryWave0<=-71;carryWave1<=117; end
39:begin carryWave0<=-81;carryWave1<=125; end
40:begin carryWave0<=-90;carryWave1<=127; end
41:begin carryWave0<=-98;carryWave1<=125; end
42:begin carryWave0<=-106;carryWave1<=117; end
43:begin carryWave0<=-112;carryWave1<=106; end
44:begin carryWave0<=-117;carryWave1<=90; end
45:begin carryWave0<=-122;carryWave1<=71; end
46:begin carryWave0<=-125;carryWave1<=49; end
47:begin carryWave0<=-126;carryWave1<=25; end
48:begin carryWave0<=-127;carryWave1<=0; end
49:begin carryWave0<=-126;carryWave1<=-25; end
50:begin carryWave0<=-125;carryWave1<=-49; end
51:begin carryWave0<=-122;carryWave1<=-71; end
52:begin carryWave0<=-117;carryWave1<=-90; end
53:begin carryWave0<=-112;carryWave1<=-106; end
54:begin carryWave0<=-106;carryWave1<=-117; end
55:begin carryWave0<=-98;carryWave1<=-125; end
56:begin carryWave0<=-90;carryWave1<=-127; end
57:begin carryWave0<=-81;carryWave1<=-125; end
58:begin carryWave0<=-71;carryWave1<=-117; end
59:begin carryWave0<=-60;carryWave1<=-106; end
60:begin carryWave0<=-49;carryWave1<=-90; end
61:begin carryWave0<=-37;carryWave1<=-71; end
62:begin carryWave0<=-25;carryWave1<=-49; end
63:begin carryWave0<=-12;carryWave1<=-25; end
endcase
end
//调制部分
always @(posedge stClk)
begin
if(codeSource)
begin
sigOut=carryWave1;
end
else
begin
sigOut=carryWave0;
end
end
endmodule
- tb_TB_FSK_modulate_mini.v(testbench仿真文件)
`timescale 10ns/10ps
module TB_FSK_modulate_mini();
reg clk;
wire [7:0]sigOut;
wire [7:0]carryWave0;
wire [7:0]carryWave1;
wire codeSource;
wire codeClk;
wire stClk;
FSK_modulate_mini Obj(
.clk (clk),
.sigOut (sigOut),
.carryWave0 (carryWave0),
.carryWave1 (carryWave1),
.codeSource (codeSource),
.codeClk (codeClk),
.stClk (stClk)
);
parameter clkper=100;
initial
begin
clk = 1'b0;
end
always
begin
#(clkper / 2) clk=~clk;
end
endmodule
③ 仿真结果