文章目錄
八、分頻器(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
③ 仿真結果