**实验一 用1个拨码开关控制所有的LED灯亮灭**
项目创建、编译和下载
**实验二**
译码器组合逻辑
2-1 放置2个2-4译码器模块,则总共有2组SW, 每组2个,2组LED,每组4个,每组SW分别控 制其对应的LED组。
module dec_2to4(
IN ,
OUT);
input [2-1:0] IN ;
output [4-1:0] OUT ;
reg [4-1:0] OUT ;
always @ (IN) begin
case(IN)
2'b00: OUT = 4'b 0001;
2'b01: OUT = 4'b 0010;
2'b10: OUT = 4'b 0100;
2'b11: OUT = 4'b 1000;
endcase
end
endmodule // module dec_2to4;
2-2 设计一个3-8译码器
module exa2(out,in);
output [8-1:0] out;
input [3-1:0] in;
reg [8-1:0] out;
always @(in)
begin
case(in)
3'd0: out=8'b00000001;
3'd1: out=8'b00000010;
3'd2: out=8'b00000100;
3'd3: out=8'b00001000;
3'd4: out=8'b00010000;
3'd5: out=8'b00100000;
3'd6: out=8'b01000000;
3'd7: out=8'b10000000;
endcase
end
endmodule
2-3 用4个拨码开关控制一个7段译码器的数字,从 0-9-A-F,共16个数字和字母
module yimaqi(out,in);
output [16-1:0] out;
input [4-1:0] in;
reg [16-1:0] out;
always @(in)
begin
case(in)
4'd0: out=16'b1111111111000000;
4'd1: out=16'b1111111111111001;
4'd2: out=16'b1111111110100100;
4'd3: out=16'b1111111110110000;
4'd4: out=16'b1111111110011001;
4'd5: out=16'b1111111110010010;
4'd6: out=16'b1111111110000010;
4'd7: out=16'b1111111111111000;
4'd8: out=16'b1111111110000000;
4'd9: out=16'b1111111110010000;
4'd10: out=16'b1111111110001000;
4'd11: out=16'b1111111110000011;
4'd12: out=16'b1111111111000110;
4'd13: out=16'b1111111110100001;
4'd14: out=16'b1111111110000110;
4'd15: out=16'b1111111110001110;
endcase
end
endmodule
实验三
计数器、波形仿真、SignalTap
3-1 设计一个0-17的计数器,当计数值为17的时,OV输出1,其他输出0
module cnt_0to17(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [6-1:0] CNTVAL;
output OV;
reg [6-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= 17)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
always @ (CNTVAL) begin
if(CNTVAL == 17)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule // module cnt_0to17
3-2 设计一个0-17的计数器,当计数值为0-8时,OV输出0;当计数值为9-17时,OV输出1
module cnt_0to17(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [6-1:0] CNTVAL;
output OV;
reg [6-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= 17)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
always @ (CNTVAL) begin
if(CNTVAL > 8)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule // module cnt_0to17
尝试并思考,如果时钟是50MHz,把OV接 到一个LED上,能看见什么现象,为什么?
猜测:小灯一亮一灭
实验:小灯一直亮
实验四 时间基准电路 和 带使能的多周期计数器
本质上是一个两级计数器级联的的电路结构 – 第一级计数器生成时间基准信号 – 第二级计数器用时间基准信号作为计数使能
4-1 后级计数器的计数范围为0-15的计数
module cnt_sync(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 25_000_000;
reg [32-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= MAX_VAL)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
always @ (CNTVAL) begin
if(CNTVAL == MAX_VAL)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule // module cnt_en_0to9
////////////////////////////////////////////////////////////////////////////////
module cnt_en_0to15(
CLK , // clock
CNTVAL, // counter value
EN ,
OV ); // overflow
input CLK;
input EN;
output [4-1:0] CNTVAL;
output OV;
reg [4-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(EN) begin // work enable
if(CNTVAL >= 15)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
else
CNTVAL <= CNTVAL ; // hold same value
end
always @ (CNTVAL) begin
if(CNTVAL == 15)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule // module cnt_en_0to15
4-2 后级计数器的计数范围为0-15,然后经过译码,在DE0 的HEXLED上显示成0-9-A-F的十六进制数
module cnt_sync(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 25_000_000;
reg [32-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= MAX_VAL)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
always @ (CNTVAL) begin
if(CNTVAL == MAX_VAL)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule // module cnt_en_0to9
////////////////////////////////////////////////////////////////////////////////
module cnt_en_0to15(
CLK , // clock
CNTVAL, // counter value
EN ,
OV ); // overflow
input CLK;
input EN;
output [4-1:0] CNTVAL;
output OV;
reg [4-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(EN) begin // work enable
if(CNTVAL >= 15)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
else
CNTVAL <= CNTVAL ; // hold same value
end
always @ (CNTVAL) begin
if(CNTVAL == 15)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule // module cnt_en_0to15
////////////////////////////////////////////////////////////////////////////////
module dec4_16(out,in);
output [16-1:0] out;
input [4-1:0] in;
reg [16-1:0] out;
always @(in)
begin
case(in)
4'd0: out=16'b1111111111000000;
4'd1: out=16'b1111111111111001;
4'd2: out=16'b1111111110100100;
4'd3: out=16'b1111111110110000;
4'd4: out=16'b1111111110011001;
4'd5: out=16'b1111111110010010;
4'd6: out=16'b1111111110000010;
4'd7: out=16'b1111111111111000;
4'd8: out=16'b1111111110000000;
4'd9: out=16'b1111111110010000;
4'd10: out=16'b1111111110001000;
4'd11: out=16'b1111111110000011;
4'd12: out=16'b1111111111000110;
4'd13: out=16'b1111111110100001;
4'd14: out=16'b1111111110000110;
4'd15: out=16'b1111111110001110;
endcase
end
endmodule
4-3 修改时间基准发生器,设计一个使用2个HEX LED,精度为0.1秒,范围为0-9.9秒的计时秒表
module cnt_sync(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 5_000_000;
reg [32-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= MAX_VAL)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
always @ (CNTVAL) begin
if(CNTVAL == MAX_VAL)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule
////////////////////////////////////////////////////////////////////////////////
module cnt_en_0to99(
CLK , // clock
CNTVAL, // counter value
EN ,
OV ); // overflow
input CLK;
input EN;
output [8-1:0] CNTVAL;
output OV;
reg [8-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(EN) begin // work enable
if(CNTVAL >= 99)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
else
CNTVAL <= CNTVAL ; // hold same value
end
always @ (CNTVAL) begin
if(CNTVAL == 99)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule // module cnt_en_0to99
////////////////////////////////////////////////////////////////////////////////
module dec4_16(out,in);
output [8-1:0] out;
input [8-1:0] in;
reg [8-1:0] out;
always @(in)
begin
case(in / 10)
4'd0: out=8'b01000000;
4'd1: out=8'b01111001;
4'd2: out=8'b00100100;
4'd3: out=8'b00110000;
4'd4: out=8'b00011001;
4'd5: out=8'b00010010;
4'd6: out=8'b00000010;
4'd7: out=8'b01111000;
4'd8: out=8'b00000000;
4'd9: out=8'b00010000;
endcase
end
endmodule
////////////////////////////////////////////////////////////////////////////////
module dec4_16L(outl,in);
output [8-1:0] outl;
input [8-1:0] in;
reg [8-1:0] outl;
always @(in)
begin
case(in % 10)
4'd0: outl=8'b11000000;
4'd1: outl=8'b11111001;
4'd2: outl=8'b10100100;
4'd3: outl=8'b10110000;
4'd4: outl=8'b10011001;
4'd5: outl=8'b10010010;
4'd6: outl=8'b10000010;
4'd7: outl=8'b11111000;
4'd8: outl=8'b10000000;
4'd9: outl=8'b10010000;
endcase
end
endmodule
**实验五 多周期移位寄存器**
本实验设计目标
• 设计时间基准电路和带使能的多周期移位寄存器
• 电路工作在50MHz
• 在每个时间基准信号有效的时钟周期
– 把一个拨码开关的状态值移位输入到寄存器的最低位
– 寄存器的每个比特送至一个LED灯上显示
– 顺序移动移位寄存器的值
//////////////////// 串入并出移位寄存器 /////////////////////////
module shift_reg_SIPO(
RST , // 异步复位, 高有效
CLK , // 时钟,上升沿有效
EN , // 输入数据串行移位使能
IN , // 输入串行数据
OUT ); // 并行输出数据
parameter SHLEN = 6;
input RST, CLK, EN;
input IN;
output[SHLEN-1:0] OUT;
reg [SHLEN-1:0] shift_R;
assign OUT[SHLEN-1:0] = shift_R[SHLEN-1:0];
// 时序逻辑 根据输入使能进行串行移位
// shift_R 会被编译为D触发器
always @ (posedge CLK or posedge RST) begin
if(RST)
shift_R[SHLEN-1:0] <= 0;
else
if(EN) begin // 串行移位的使能有效
shift_R[SHLEN-1:1] <= shift_R[SHLEN-2:0];
shift_R[0] <= IN;
end
else begin // 使能无效保持不动
shift_R[SHLEN-1:0] <= shift_R[SHLEN-1:0];
end
end // always
endmodule
//////////////////// 时间基准计数器 /////////////////////////
module cnt_sync(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 25_000_000;
reg [32-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= MAX_VAL)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
always @ (CNTVAL) begin
if(CNTVAL == MAX_VAL)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule
现象:当开关sw0=1时,从LED0亮到LED5;当开关sw0=0时,从LED0灭到LED5。
• 设计新的功能
– 在原有的电路基础上,添加方向选择功能。
– SW0仍然是移位寄存器组的输入
– 使用SW1开关,控制移位寄存的方向
– 从实验现象上应当能够看到,SW1可以控制LED闪烁的 移动方向,以及控制SW0值的对LED组的输入位置(即 从LED组的最左边或是最右边)
入并出移位寄存器
module shift_reg_SIPO(
RST , // 异步复位, 高有效
CLK , // 时钟,上升沿有效
EN , // 输入数据串行移位使能
IN0 , // 输入串行数据
IN1 , // fangxiangkongzhi
OUT ); // 并行输出数据
parameter SHLEN = 6;
input RST, CLK, EN;
input IN0;
input IN1;
output[SHLEN-1:0] OUT;
reg [SHLEN-1:0] shift_R;
assign OUT[SHLEN-1:0] = shift_R[SHLEN-1:0];
// 时序逻辑 根据输入使能进行串行移位
// shift_R 会被编译为D触发器
always @ (posedge CLK or posedge RST) begin
if(RST)
shift_R[SHLEN-1:0] <= 0;
else
if(EN) begin // 串行移位的使能有效
if(IN1) begin
shift_R[SHLEN-1:1] <= shift_R[SHLEN-2:0];
shift_R[0] <= IN0;
end
else begin
shift_R[SHLEN-2:0] <= shift_R[SHLEN-1:1];
shift_R[5] <= IN0;
end
end
else begin // 使能无效保持不动
shift_R[SHLEN-1:0] <= shift_R[SHLEN-1:0];
end
end // always
endmodule
//////////////////// 时间基准计数器 /////////////////////////
module cnt_sync(
CLK , // clock
CNTVAL, // counter value
OV ); // overflow
input CLK;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 25_000_000;
reg [32-1:0] CNTVAL;
reg OV;
always @ (posedge CLK) begin
if(CNTVAL >= MAX_VAL)
CNTVAL <= 0;
else
CNTVAL <= CNTVAL + 1'b1;
end
always @ (CNTVAL) begin
if(CNTVAL == MAX_VAL)
OV = 1'b1;
else
OV = 1'b0;
end
endmodule
实验6 计数器、ROM和DDS
本实验设计目标
• 认识ROM
• 用计数器生成地址、读取ROM数据
• 用SignalTAP观察ROM的输出波形
• 理解二进制补码和无符号数
• 修改计数增量值,观察波形变化,思考输出频率 和计数器增量值的关系。
module cnt_incr(
CLK , // clock
INCR , // counter increase value
CNTVAL); // counter value
input CLK;
input [7-1:0] INCR;
output [7-1:0] CNTVAL;
reg [7-1:0] CNTVAL;
always @ (posedge CLK) begin
CNTVAL <= INCR + CNTVAL;
end
endmodule // module cnt_incr
module sine_rom(
CLK , // clock
RA , // read address
RD ); // read data
input CLK;
input [6 :0] RA;
output [7 :0] RD;
reg [7 :0] RD;
always @ (posedge CLK)
case(RA)
7 'd 0 :RD = #1 8 'b 00000000; // 0 0x0
7 'd 1 :RD = #1 8 'b 00000110; // 6 0x6
7 'd 2 :RD = #1 8 'b 00001100; // 12 0xC
7 'd 3 :RD = #1 8 'b 00010010; // 18 0x12
7 'd 4 :RD = #1 8 'b 00011000; // 24 0x18
7 'd 5 :RD = #1 8 'b 00011110; // 30 0x1E
7 'd 6 :RD = #1 8 'b 00100100; // 36 0x24
7 'd 7 :RD = #1 8 'b 00101010; // 42 0x2A
7 'd 8 :RD = #1 8 'b 00110000; // 48 0x30
7 'd 9 :RD = #1 8 'b 00110110; // 54 0x36
7 'd 10 :RD = #1 8 'b 00111011; // 59 0x3B
7 'd 11 :RD = #1 8 'b 01000001; // 65 0x41
7 'd 12 :RD = #1 8 'b 01000110; // 70 0x46
7 'd 13 :RD = #1 8 'b 01001011; // 75 0x4B
7 'd 14 :RD = #1 8 'b 01010000; // 80 0x50
7 'd 15 :RD = #1 8 'b 01010101; // 85 0x55
7 'd 16 :RD = #1 8 'b 01011001; // 89 0x59
7 'd 17 :RD = #1 8 'b 01011110; // 94 0x5E
7 'd 18 :RD = #1 8 'b 01100010; // 98 0x62
7 'd 19 :RD = #1 8 'b 01100110; // 102 0x66
7 'd 20 :RD = #1 8 'b 01101001; // 105 0x69
7 'd 21 :RD = #1 8 'b 01101100; // 108 0x6C
7 'd 22 :RD = #1 8 'b 01110000; // 112 0x70
7 'd 23 :RD = #1 8 'b 01110010; // 114 0x72
7 'd 24 :RD = #1 8 'b 01110101; // 117 0x75
7 'd 25 :RD = #1 8 'b 01110111; // 119 0x77
7 'd 26 :RD = #1 8 'b 01111001; // 121 0x79
7 'd 27 :RD = #1 8 'b 01111011; // 123 0x7B
7 'd 28 :RD = #1 8 'b 01111100; // 124 0x7C
7 'd 29 :RD = #1 8 'b 01111101; // 125 0x7D
7 'd 30 :RD = #1 8 'b 01111110; // 126 0x7E
7 'd 31 :RD = #1 8 'b 01111110; // 126 0x7E
7 'd 32 :RD = #1 8 'b 01111111; // 127 0x7F
7 'd 33 :RD = #1 8 'b 01111110; // 126 0x7E
7 'd 34 :RD = #1 8 'b 01111110; // 126 0x7E
7 'd 35 :RD = #1 8 'b 01111101; // 125 0x7D
7 'd 36 :RD = #1 8 'b 01111100; // 124 0x7C
7 'd 37 :RD = #1 8 'b 01111011; // 123 0x7B
7 'd 38 :RD = #1 8 'b 01111001; // 121 0x79
7 'd 39 :RD = #1 8 'b 01110111; // 119 0x77
7 'd 40 :RD = #1 8 'b 01110101; // 117 0x75
7 'd 41 :RD = #1 8 'b 01110010; // 114 0x72
7 'd 42 :RD = #1 8 'b 01110000; // 112 0x70
7 'd 43 :RD = #1 8 'b 01101100; // 108 0x6C
7 'd 44 :RD = #1 8 'b 01101001; // 105 0x69
7 'd 45 :RD = #1 8 'b 01100110; // 102 0x66
7 'd 46 :RD = #1 8 'b 01100010; // 98 0x62
7 'd 47 :RD = #1 8 'b 01011110; // 94 0x5E
7 'd 48 :RD = #1 8 'b 01011001; // 89 0x59
7 'd 49 :RD = #1 8 'b 01010101; // 85 0x55
7 'd 50 :RD = #1 8 'b 01010000; // 80 0x50
7 'd 51 :RD = #1 8 'b 01001011; // 75 0x4B
7 'd 52 :RD = #1 8 'b 01000110; // 70 0x46
7 'd 53 :RD = #1 8 'b 01000001; // 65 0x41
7 'd 54 :RD = #1 8 'b 00111011; // 59 0x3B
7 'd 55 :RD = #1 8 'b 00110110; // 54 0x36
7 'd 56 :RD = #1 8 'b 00110000; // 48 0x30
7 'd 57 :RD = #1 8 'b 00101010; // 42 0x2A
7 'd 58 :RD = #1 8 'b 00100100; // 36 0x24
7 'd 59 :RD = #1 8 'b 00011110; // 30 0x1E
7 'd 60 :RD = #1 8 'b 00011000; // 24 0x18
7 'd 61 :RD = #1 8 'b 00010010; // 18 0x12
7 'd 62 :RD = #1 8 'b 00001100; // 12 0xC
7 'd 63 :RD = #1 8 'b 00000110; // 6 0x6
7 'd 64 :RD = #1 8 'b 00000000; // 0 0x0
7 'd 65 :RD = #1 8 'b 11111010; // -6 0xFA
7 'd 66 :RD = #1 8 'b 11110100; // -12 0xF4
7 'd 67 :RD = #1 8 'b 11101110; // -18 0xEE
7 'd 68 :RD = #1 8 'b 11101000; // -24 0xE8
7 'd 69 :RD = #1 8 'b 11100010; // -30 0xE2
7 'd 70 :RD = #1 8 'b 11011100; // -36 0xDC
7 'd 71 :RD = #1 8 'b 11010110; // -42 0xD6
7 'd 72 :RD = #1 8 'b 11010000; // -48 0xD0
7 'd 73 :RD = #1 8 'b 11001010; // -54 0xCA
7 'd 74 :RD = #1 8 'b 11000101; // -59 0xC5
7 'd 75 :RD = #1 8 'b 10111111; // -65 0xBF
7 'd 76 :RD = #1 8 'b 10111010; // -70 0xBA
7 'd 77 :RD = #1 8 'b 10110101; // -75 0xB5
7 'd 78 :RD = #1 8 'b 10110000; // -80 0xB0
7 'd 79 :RD = #1 8 'b 10101011; // -85 0xAB
7 'd 80 :RD = #1 8 'b 10100111; // -89 0xA7
7 'd 81 :RD = #1 8 'b 10100010; // -94 0xA2
7 'd 82 :RD = #1 8 'b 10011110; // -98 0x9E
7 'd 83 :RD = #1 8 'b 10011010; // -102 0x9A
7 'd 84 :RD = #1 8 'b 10010111; // -105 0x97
7 'd 85 :RD = #1 8 'b 10010100; // -108 0x94
7 'd 86 :RD = #1 8 'b 10010000; // -112 0x90
7 'd 87 :RD = #1 8 'b 10001110; // -114 0x8E
7 'd 88 :RD = #1 8 'b 10001011; // -117 0x8B
7 'd 89 :RD = #1 8 'b 10001001; // -119 0x89
7 'd 90 :RD = #1 8 'b 10000111; // -121 0x87
7 'd 91 :RD = #1 8 'b 10000101; // -123 0x85
7 'd 92 :RD = #1 8 'b 10000100; // -124 0x84
7 'd 93 :RD = #1 8 'b 10000011; // -125 0x83
7 'd 94 :RD = #1 8 'b 10000010; // -126 0x82
7 'd 95 :RD = #1 8 'b 10000010; // -126 0x82
7 'd 96 :RD = #1 8 'b 10000001; // -127 0x81
7 'd 97 :RD = #1 8 'b 10000010; // -126 0x82
7 'd 98 :RD = #1 8 'b 10000010; // -126 0x82
7 'd 99 :RD = #1 8 'b 10000011; // -125 0x83
7 'd 100 :RD = #1 8 'b 10000100; // -124 0x84
7 'd 101 :RD = #1 8 'b 10000101; // -123 0x85
7 'd 102 :RD = #1 8 'b 10000111; // -121 0x87
7 'd 103 :RD = #1 8 'b 10001001; // -119 0x89
7 'd 104 :RD = #1 8 'b 10001011; // -117 0x8B
7 'd 105 :RD = #1 8 'b 10001110; // -114 0x8E
7 'd 106 :RD = #1 8 'b 10010000; // -112 0x90
7 'd 107 :RD = #1 8 'b 10010100; // -108 0x94
7 'd 108 :RD = #1 8 'b 10010111; // -105 0x97
7 'd 109 :RD = #1 8 'b 10011010; // -102 0x9A
7 'd 110 :RD = #1 8 'b 10011110; // -98 0x9E
7 'd 111 :RD = #1 8 'b 10100010; // -94 0xA2
7 'd 112 :RD = #1 8 'b 10100111; // -89 0xA7
7 'd 113 :RD = #1 8 'b 10101011; // -85 0xAB
7 'd 114 :RD = #1 8 'b 10110000; // -80 0xB0
7 'd 115 :RD = #1 8 'b 10110101; // -75 0xB5
7 'd 116 :RD = #1 8 'b 10111010; // -70 0xBA
7 'd 117 :RD = #1 8 'b 10111111; // -65 0xBF
7 'd 118 :RD = #1 8 'b 11000101; // -59 0xC5
7 'd 119 :RD = #1 8 'b 11001010; // -54 0xCA
7 'd 120 :RD = #1 8 'b 11010000; // -48 0xD0
7 'd 121 :RD = #1 8 'b 11010110; // -42 0xD6
7 'd 122 :RD = #1 8 'b 11011100; // -36 0xDC
7 'd 123 :RD = #1 8 'b 11100010; // -30 0xE2
7 'd 124 :RD = #1 8 'b 11101000; // -24 0xE8
7 'd 125 :RD = #1 8 'b 11101110; // -18 0xEE
7 'd 126 :RD = #1 8 'b 11110100; // -12 0xF4
7 'd 127 :RD = #1 8 'b 11111010; // -6 0xFA
default : RD = #1 0;
endcase
endmodule
• 拨动开关,观察不同频率的正弦波 – 电路的工作时钟是50MHz
– 请回答,你能得到的正弦波频率和计数器增量值的对应关系是什么?
– 请回答,你能得到的最低频率的正弦波是多少?设该频率为f1
– 请思考,能否有什么方法能够得到比f1频率还低的正弦波
一:正弦波频率和计数器增量值成正比
二:f1=50M/512=0.098MHz
三:我们看到最后的输出时钟是由采样时钟和地址深度决定的,所以可以通过对这两个地方着手更改,首先先看下采样时钟,原来是每个时钟的作用下,采集数据加1,现在可以通过对时钟计数,然后让地址在两个时钟作用下采集1,这样就可以实现分频的目的。说完采样时钟,那么看下地址深度的问题,因为地址深度是由定制ROM时,就已经确认下来的,所以不能直接更改地址深度,但是可通过更改读取ROM的地址,使其只读其中的一半等,也可以达到效果。 有奈奎斯特采样原理我们知道,在做ADDA转换的过程当中,采样频率要大于信号最高频率的两倍,才能保证信号不失真,这个方法说白了其实就是改变采样的点数,然后达到倍频的目的,不过因为这样做,点数采样的比较少,会导致波形失真。
• 对计数器进行改动,修改计数增量信号为10比特,计数值信号为10比特。 – 把计数增量输入信号分配到10个拨码开关上 – 把计数值信号的高7位分配为ROM的地址,低3位悬空不使用。 – 编译、下载电路,拨动拨码开关,观察最低频率有什么变化。
module cnt_incr(
CLK , // clock
INCR , // counter increase value
CNTVAL); // counter value
input CLK;
input [10-1:0] INCR;
output [10-1:0] CNTVAL;
reg [10-1:0] CNTVAL;
always @ (posedge CLK) begin
CNTVAL <= INCR + CNTVAL;
end
endmodule // module cnt_incr
• 这种电路有个好听的名字,叫做 直接数字频率合成(DDS)
– 请给出:输出信号频率和电路工作时钟频率,计数器增量值,以及计数器数据位宽之间的表达式关系。
式中输出信号频率Fout,电路工作时钟频率Fdk,计数器增N
值B,以及计数器数据位宽N