Verilog HDL计数器组合电路(作业2)

目录

      • 目录
  • 实验内容一
    • Visio绘制的RTL
    • Quartus扫描生成的RTL
    • 计数值的SignalTap截图
    • 代码
  • 实验内容二
    • Visio绘制的RTL
    • Quartus扫描生成的RTL
    • 计数值的SignalTap截图
    • 代码

实验内容一

使用Veriog - HDL语言,DE0 FPGA开发板在 DE0 开发板的最右侧的 HEX LED 数码管上,进行计数并用十进制数进行显示。计数器特征如下:

该计数器在电路复位后会循环的从0值递增计数到最大值,计数最大值是一个循环变化的过程,计数器复位之后,第一次计数最大值是6,然后是7、8、9,然后计数最大值又变成6,如此往复循环, 计数数值变化的时间间隔是1秒 ,计数过程如下所示:

0 1 … 6 0 1 … 7 0 1 … 8 0 1 …9 0 1 … 6

Visio绘制的RTL

Verilog HDL计数器组合电路(作业2)_第1张图片
其中,max表示计数最大值;CNTVAL表示计数值,计数最大值要依次加一,加到9时再变为6。max[3..0]和CNTVAL[3..0]构成D触发器。CLK为1s周期。

Quartus扫描生成的RTL

顶层RTL:
Verilog HDL计数器组合电路(作业2)_第2张图片
cnt_sync为第一级计数器,其OV输出端用于产生1s的时钟信号;
cnt_0to9为第二级计数器,用于产生显示的计数值;
tubedec_4to16为数码管译码电路。
cnt_0to9底层RTL:
Verilog HDL计数器组合电路(作业2)_第3张图片

计数值的SignalTap截图

Verilog HDL计数器组合电路(作业2)_第4张图片

代码

Verilog HDL代码:

module cnt_sync(
  RESET ,
  CLK   ,   // clock
  CNTVAL,   // counter value
  OV    );  // overflow
input CLK,RESET;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 50_000_000;  //50MHz下为1s
reg [32-1:0] CNTVAL;
reg OV;

always @ (posedge CLK) 
begin
  if (!RESET) 
  begin
    CNTVAL <= 0;
  end
  else
  begin
    if(CNTVAL >= MAX_VAL)
      CNTVAL <= 0;
    else
      CNTVAL <= CNTVAL + 1'b1;  
  end
end

always @ (CNTVAL) begin
  if(CNTVAL == MAX_VAL)
    OV = 1'b1;
  else
    OV = 1'b0;
end

endmodule   // module cnt_sync
////////////////////////////////////////////////////////
module cnt_en_0to9(
  EN    ,
  RESET ,
  CLK   ,   // clock
  CNTVAL);   // counter value
//  OV    );  // overflow
input CLK,RESET,EN;
output [4-1:0] CNTVAL;
//output OV;

reg [4-1:0] CNTVAL;
//reg OV;
reg [4-1:0] max=6;  

always @ (posedge CLK or negedge RESET) 
begin
  if(!RESET)  //when rst, set max=6
  begin
    max <= 6;   
    CNTVAL <= 0;
  end 
  else if(EN)
  begin
    if(CNTVAL >= max)   //when OV, max++, if max=9,then max=6
    begin
      CNTVAL <= 0;
      max <= max + 1'b1;
      if (max >= 9) 
        max <= 6;
    end
    else
      CNTVAL <= CNTVAL + 1'b1;
  end
  else
    CNTVAL <= CNTVAL;
end

// always @ (CNTVAL) 
// begin
//   if(CNTVAL == max)
//   begin
//     OV = 1'b1;
//   end 
//   else
//     OV = 1'b0;
// end

endmodule   // module cnt_en_0to9
///////////////////////////////////////////////////////
module tubedec_4to16(IN,OUT);
input[3:0]  IN;
output reg[7:0] OUT;
always @(IN)
begin
  case(IN)
    4'h0: OUT=8'hc0;
    4'h1: OUT=8'hf9;
    4'h2: OUT=8'ha4;
    4'h3: OUT=8'hb0;
    4'h4: OUT=8'h99;
    4'h5: OUT=8'h92;
    4'h6: OUT=8'h82;
    4'h7: OUT=8'hf8;
    4'h8: OUT=8'h80;
    4'h9: OUT=8'h90;
    4'hA: OUT=8'h88;
    4'hB: OUT=8'h83;
    4'hC: OUT=8'hc6;
    4'hD: OUT=8'ha1;
    4'hE: OUT=8'h86;
    4'hF: OUT=8'h8e;
    default: OUT=8'hff;
  endcase
end

endmodule

实验内容二

在 DE0 开发板的 从左到右 的 4个HEX LED 数码管上,进行计数并用十进制数进行显示。计数器特征如下:

  • 系统复位后全部HEX LED熄灭
  • 左1 LED,显示 0、1、2 ~6 ,然后熄灭
  • 左2 LED,显示 0、1、2 ~7 ,然后熄灭
  • 左3 LED,显示 0、1、2 ~8 ,然后熄灭
  • 最右侧 LED,显示 0、1、2 ~9 ,然后熄灭
  • 然后再开始左1 LED, 显示 0、1、2~6 如此一直循环。
  • 所有情况下,计数数值变化的时间间隔是1秒

Visio绘制的RTL

Verilog HDL计数器组合电路(作业2)_第5张图片
和实验一cnt_0to9计数器差不多,仅增加了OV进位端。

Quartus扫描生成的RTL

顶层RTL:
Verilog HDL计数器组合电路(作业2)_第6张图片顶层RTL涉及:
cnt_sync为第一级计数器,其OV输出端用于产生1s的时钟信号;
cnt_0to9为第二级计数器,用于产生显示的计数值及数码管选择器的CLK信号;
dec_CLKto4为数码管选择器,用于产生数码管译码器使能信号,控制数码管何时点亮;
tubedec_en_4to16为数码管译码器,带有使能控制端,输出为共阳极数码管段选信号。

cnt_0to9底层RTL:
Verilog HDL计数器组合电路(作业2)_第7张图片

计数值的SignalTap截图

计数器计数的SignalTap:
Verilog HDL计数器组合电路(作业2)_第8张图片
轮流选择四个数码管:
Verilog HDL计数器组合电路(作业2)_第9张图片

代码

module cnt_sync(
  RESET ,
  CLK   ,   // clock
  CNTVAL,   // counter value
  OV    );  // overflow
input CLK,RESET;
output [32-1:0] CNTVAL;
output OV;
parameter MAX_VAL = 50_000_000;  //50MHz下为1s
reg [32-1:0] CNTVAL;
reg OV;

always @ (posedge CLK) 
begin
  if (!RESET) 
  begin
    CNTVAL <= 0;
  end
  else
  begin
    if(CNTVAL >= MAX_VAL)
      CNTVAL <= 0;
    else
      CNTVAL <= CNTVAL + 1'b1;  
  end
end

always @ (CNTVAL) begin
  if(CNTVAL == MAX_VAL)
    OV = 1'b1;
  else
    OV = 1'b0;
end

endmodule   // module cnt_sync
///////////////////////////////////////////////////////
module cnt_en_0to9(
  EN    ,
  RESET ,
  CLK   ,   // clock
  CNTVAL,   // counter value
  OV    );  // overflow
input CLK,RESET,EN;
output [4-1:0] CNTVAL;
output OV;

reg [4-1:0] CNTVAL;
reg OV;
reg [4-1:0] max=6;  

always @ (posedge CLK or negedge RESET) 
begin
  if(!RESET)  //when rst, set max=6
  begin
    max <= 6;   
    CNTVAL <= 0;
  end 
  else if(EN)
  begin          //when OV, max++, if max=9,then max=6
    if(CNTVAL >= max)   
    begin
      CNTVAL <= 0;
      max <= max + 1'b1;
      if (max >= 9) 
        max <= 6;
    end
    else
      CNTVAL <= CNTVAL + 1'b1;
  end
  else
    CNTVAL <= CNTVAL;
end

always @ (CNTVAL) 
begin
  if(CNTVAL == max)
  begin
    OV = 1'b1;
  end 
  else
    OV = 1'b0;
end

endmodule   // module cnt_en_0to9
//////////////////////////////////////////////////////
module dec_ento4(
EN,
RESET,
OUT);
input RESET,EN;
output [4-1:0] OUT ;

reg [4-1:0] OUT ;
reg [3:0] CNT;

always @(negedge EN or negedge RESET) 
begin
  if (!RESET)
    CNT <= 0;
  else   
  begin
    if (CNT >= 3) 
      CNT <= 0;
    else 
      CNT <= CNT + 1'b1;
  end
end

always @ (CNT) begin
  case(CNT)
    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_ento4;

///////////////////////////////////////////////////////
module tubedec_en_4to16(IN,OUT,EN);
input EN;
input[3:0]  IN;
output reg[7:0] OUT;
always @(IN)
begin
  if(EN)
  begin
    case(IN)
      4'h0: OUT=8'hc0;
      4'h1: OUT=8'hf9;
      4'h2: OUT=8'ha4;
      4'h3: OUT=8'hb0;
      4'h4: OUT=8'h99;
      4'h5: OUT=8'h92;
      4'h6: OUT=8'h82;
      4'h7: OUT=8'hf8;
      4'h8: OUT=8'h80;
      4'h9: OUT=8'h90;
      4'hA: OUT=8'h88;
      4'hB: OUT=8'h83;
      4'hC: OUT=8'hc6;
      4'hD: OUT=8'ha1;
      4'hE: OUT=8'h86;
      4'hF: OUT=8'h8e;
    endcase
  end
  else 
  begin
    OUT=8'hff;  
  end
end

endmodule

你可能感兴趣的:(Verilog)