此文章是vip文章,如何查看?  

1,点击链接获取密钥 http://nicethemes.cn/product/view29882.html

2,在下方输入文章查看密钥即可立即查看当前vip文章


计数器 FPGA电路实验 作业2

  • 时间:
  • 浏览:
  • 来源:互联网

实验内容 1

使用Veriog - HDL 语言,DE0 FPGA 开发板 按照如下要求设计一个计数器电路 。

功能描述

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

只能使用一个50MHz的时钟信号,不要有计数器分频的信号作为时钟

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

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

人工绘制的电路结构RTL设计图

顶层BDF图如下:
这里写图片描述
1.div模块为分频器用于将50MHz时钟信号分频产生1s时钟信号在clk_div输出。
2.count模块为产生符合技术要求的计数器。
3.decoder_hex模块为4-7译码器,译码使在数码管上显示对应字符。
div模块人工绘制的RTL图:
这里写图片描述

Quartus扫描生成的电路RTL图

这里写图片描述

计数器的计数值的SignalTap截图

这里写图片描述

实验代码

******************分频器代码******************
module div(
    clk   ,   // clock
    reset,
    CNTVAL,   // counter value
    clk_div);  // overflow
input clk;
input reset; 
output [32-1:0] CNTVAL;
output clk_div;
parameter MAX_VAL = 50_000_000;  //50MHz下为1s
reg [32-1:0] CNTVAL;
reg clk_div;
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)
    clk_div = 1'b1;
  else
    clk_div = 1'b0;
end
endmodule
******************计数器代码******************
module count(
    clk,
    cnt,
    OV);
input clk,rst;
output reg[3:0] cnt;
output OV;
reg[1:0] state,next_state;
reg[3:0] cnt_temp;
parameter s0=2'b00,s1=2'b01,s2=2'b11,s3=2'b10;

always@( next_state or rst)
begin
    if(rst)
        begin
        state=s0;
        cnt=0;
        end
    else
        begin
        state=next_state;
        cnt=cnt_temp;
        end
end

always@(posedge clk)
begin
    if(state == s0 && cnt == 0)
    begin
    cnt_temp=0;
    next_state=s0;
    end
    case(state)
    s0:begin
        if(cnt_temp>=6)
            begin
            cnt_temp=0;
            next_state=s1;
            end
        else
            begin
            cnt_temp=cnt_temp+1;
            end
        end
    s1:begin
        if(cnt_temp>=7)
            begin
            cnt_temp=0;
            next_state=s2;
            end 
        else
            begin
            cnt_temp=cnt_temp+1;
            end
       end
    s2:begin
        if(cnt_temp>=8)
            begin
            cnt_temp=0;
            next_state=s3;
            end 
        else
            begin
            cnt_temp=cnt_temp+1;
            end
       end
    s3:begin
        if(cnt_temp>=9)
            begin
            cnt_temp=0;
            next_state=s0;
            end
        else
            begin
            cnt_temp=cnt_temp+1;
            end
        end
    default:begin
        next_state=s0;
        cnt_temp=0;
        end
    endcase
end
endmodule
******************数码管译码器代码******************
module decoder_hex(
    data_in,
    EN,
    data_out);
input [3:0] data_in ;
input EN ;
output [6:0] data_out ;
reg [6:0] data_out ;

always @(data_in or EN )
begin
        data_out = 7'b1111111;
if (EN == 1)
    case (data_in)
        4'b0000: data_out = 7'b1000000; // 0
        4'b0001: data_out = 7'b1111001; // 1
        4'b0010: data_out = 7'b0100100; // 2
        4'b0011: data_out = 7'b0110000; // 3
        4'b0100: data_out = 7'b0011001; // 4
        4'b0101: data_out = 7'b0010010; // 5
        4'b0110: data_out = 7'b0000011; // 6
        4'b0111: data_out = 7'b1111000; // 7
        4'b1000: data_out = 7'b0000000; // 8
        4'b1001: data_out = 7'b0011000; // 9
        4'b1010: data_out = 7'b0001000; // A
        4'b1011: data_out = 7'b0000011; // b
        4'b1100: data_out = 7'b1000110; // c
        4'b1101: data_out = 7'b0100001; // d
        4'b1110: data_out = 7'b0000110; // E
        4'b1111: data_out = 7'b0001110; // F
        default: data_out = 7'b1111111; //不显示
    endcase
end
endmodule

计数过程链接

https://v.qq.com/x/page/s0354tkg3d2.html

===================================================

实验内容 2

功能描述

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

只能使用一个50MHz的时钟信号,不要有计数器分频的信号作为时钟
系统复位后全部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秒

人工绘制的电路结构RTL设计图

顶层BDF图如下:
这里写图片描述
1.div模块为分频器用于将50MHz时钟信号分频产生1s时钟信号在clk_div输出。
2.count模块为产生符合技术要求的计数器。
3.decoder_hex模块为4-7译码器,译码使在数码管上显示对应字符。
4.select模块OV端输出信号分别使能四个译码器,产生移位效果。
select模块人工绘制的RTL图:
这里写图片描述

Quartus扫描生成的电路RTL图

这里写图片描述
Quartus扫描生成的电路select模块RTL图:
这里写图片描述
状态机的状态转移图和表达式:
这里写图片描述

计数器的计数值的SignalTap截图

这里写图片描述

实验代码

******************分频器代码******************
module div(
    clk   ,   // clock
    reset,
    CNTVAL,   // counter value
    clk_div);  // overflow
input clk;
input reset; 
output [32-1:0] CNTVAL;
output clk_div;
parameter MAX_VAL = 50_000_000;  //50MHz下为1s
reg [32-1:0] CNTVAL;
reg clk_div;
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)
    clk_div = 1'b1;
  else
    clk_div = 1'b0;
end
endmodule
******************计数器代码******************
module count(
    clk,
    cnt,
    OV);
input clk,rst;
output reg[3:0] cnt;
output OV;
reg[1:0] state,next_state;
reg[3:0] cnt_temp;
parameter s0=2'b00,s1=2'b01,s2=2'b11,s3=2'b10;

always@( next_state or rst)
begin
    if(rst)
        begin
        state=s0;
        cnt=0;
        end
    else
        begin
        state=next_state;
        cnt=cnt_temp;
        end
end

always@(posedge clk)
begin
    if(state == s0 && cnt == 0)
    begin
    cnt_temp=0;
    next_state=s0;
    end
    case(state)
    s0:begin
        if(cnt_temp>=6)
            begin
            cnt_temp=0;
            next_state=s1;
            end
        else
            begin
            cnt_temp=cnt_temp+1;
            end
        end
    s1:begin
        if(cnt_temp>=7)
            begin
            cnt_temp=0;
            next_state=s2;
            end 
        else
            begin
            cnt_temp=cnt_temp+1;
            end
       end
    s2:begin
        if(cnt_temp>=8)
            begin
            cnt_temp=0;
            next_state=s3;
            end 
        else
            begin
            cnt_temp=cnt_temp+1;
            end
       end
    s3:begin
        if(cnt_temp>=9)
            begin
            cnt_temp=0;
            next_state=s0;
            end
        else
            begin
            cnt_temp=cnt_temp+1;
            end
        end
    default:begin
        next_state=s0;
        cnt_temp=0;
        end
    endcase
end
endmodule
******************数码管译码器代码******************
module decoder_hex(
    data_in,
    EN,
    data_out);
input [3:0] data_in ;
input EN ;
output [6:0] data_out ;
reg [6:0] data_out ;

always @(data_in or EN )
begin
        data_out = 7'b1111111;
if (EN == 1)
    case (data_in)
        4'b0000: data_out = 7'b1000000; // 0
        4'b0001: data_out = 7'b1111001; // 1
        4'b0010: data_out = 7'b0100100; // 2
        4'b0011: data_out = 7'b0110000; // 3
        4'b0100: data_out = 7'b0011001; // 4
        4'b0101: data_out = 7'b0010010; // 5
        4'b0110: data_out = 7'b0000011; // 6
        4'b0111: data_out = 7'b1111000; // 7
        4'b1000: data_out = 7'b0000000; // 8
        4'b1001: data_out = 7'b0011000; // 9
        4'b1010: data_out = 7'b0001000; // A
        4'b1011: data_out = 7'b0000011; // b
        4'b1100: data_out = 7'b1000110; // c
        4'b1101: data_out = 7'b0100001; // d
        4'b1110: data_out = 7'b0000110; // E
        4'b1111: data_out = 7'b0001110; // F
        default: data_out = 7'b1111111; //不显示
    endcase
end
endmodule
******************选择器代码******************
module select(
    IN          ,
    RESET       ,
    OV          );  
input   IN;
input   RESET;
output  OV;
parameter ST_INIT = 4'b0000;
parameter ST_0 = 4'b0001;
parameter ST_1 = 4'b0010;
parameter ST_2 = 4'b0100;
parameter ST_3 = 4'b1000;

reg[3:0] OV_temp;
reg[3:0] OV;

always@(RESET)
begin
    if(RESET)
        begin
        OV<=ST_INIT;
        end
    else
        begin
        OV<=OV_temp;
        end
end

always @ (posedge IN) begin
  case (OV_temp)
    ST_0 :begin if(IN==1) OV_temp <= ST_1 ; else OV_temp <= ST_0; end
    ST_1 :begin if(IN==1) OV_temp <= ST_2 ; else OV_temp <= ST_1; end
    ST_2 :begin if(IN==1) OV_temp <= ST_3 ; else OV_temp <= ST_2; end
    ST_3 :begin if(IN==1) OV_temp <= ST_0 ; else OV_temp <= ST_3; end
  endcase
end
endmodule

计数过程链接

https://v.qq.com/x/page/f0354lminbu.html

本文链接http://element-ui.cn/news/show-577073.aspx