FPGA 电路开发入门实验

             **实验一   用1个拨码开关控制所有的LED灯亮灭** 

项目创建、编译和下载
电路原理图

指派管脚图

sw0控制10个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-4译码器原理图

两组2-4译码器指派管脚图

00-0

01-1

10-2

11-3
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

3-8译码器原理图

3-8译码器指派管脚图
000-0
001-1
010-2
011-3
100-4
101-5
110-6
111-7

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

原理图
指派管脚
0
1
2
3
4
5
6
7
8
9
A
B
C
D
E
F
实验三
计数器、波形仿真、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

原理图
RTL图
管脚指派图
仿真图

signaltap图

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

原理图

RTL导图

指派管脚图

仿真图

signaltap图
尝试并思考,如果时钟是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

原理图
RTL图
signaltap图
signaltap图
signaltap图
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

原理图
RTL图

                **实验五 多周期移位寄存器** 

本实验设计目标
• 设计时间基准电路和带使能的多周期移位寄存器
• 电路工作在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  

原理图
RTL导图
管脚指派图
现象:当开关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 

原理图
RTL导图
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
• 拨动开关,观察不同频率的正弦波 – 电路的工作时钟是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

猜你喜欢

转载自blog.csdn.net/a646123070/article/details/78452653