Chisel(Constructing Hardware In a Scala Embedded Language)是UC Berkeley开发的一种开源硬件构造语言。
站长xddcore有话说:在我大二的时候,因为项目需要,接触了Chisel。在体验过后,我被它深深的吸引了。我幻想着它十年后的样子,充满希望。于是创建了这个博客,让更多人的了解Chisel,学习Chisel。

FPGA学习之路(三)之BCD码生成器(BCD Generator)搭建

内容纲要
Reading Time: 2 minutes

Hello,大家好,好久不见,这里是xddcore。在先前的博客中,说要搭建一个用于生成0-9BCD码驱动BCD译码器的 BCD码生成器。折腾了两天,总算弄好了。

BCD码生成器组成结构

在这里插入图片描述如上图所示,BCD码生成器由四个D类触发器和2个十进制计数器够成,纯数字电路设计,怀旧风满满。(嘿嘿嘿

下面简单说一下每个元件的用途。首先,4个D类触发器用于0-16(4bit binary)循环计数输入的脉冲。其次,两个十进制计数器用于将循环计数脉冲由0-16变为0-9.(每次进位到十位时,便复位4个D类触发器
)
这个原理在proteus上仿真通过了(详细的原理介绍可见博客Simulation method and working principle of test circuit章节:https://blog.csdn.net/qq_36229876/article/details/107728996)。

于是,刚好最近在折腾FPGA,我在想能不能用FPGA捏一下这个电路。首先根据真值表捏一下D类触发器和十进制计数器。他们的教程和仿真见下博客链接:
D类触发器:https://blog.csdn.net/qq_36229876/article/details/107782813
十进制计数器:https://blog.csdn.net/qq_36229876/article/details/107787179

特别值得注意的是,由于我之前写惯了单片机,导致以上module都是组合逻辑QAQ,虽然RTL仿真可以过,但是门级仿真结果,ABCD输出一直为0.解决办法见如下博客:https://blog.csdn.net/qq_36229876/article/details/107876809

TOP文件

`timescale 1ns / 1ps

module bcd_generator(
    SYS_RST, //复位信号
    SYS_CLK, //时钟信号
    OUTPUT_A, //BCD-1 (MSB)
    OUTPUT_B, //BCD-2
    OUTPUT_C, //BCD-3
    OUTPUT_D //BCD-4(LSB)
);

input SYS_RST;
input SYS_CLK;
output OUTPUT_A;
output OUTPUT_B;
output OUTPUT_C;
output OUTPUT_D;

wire QN_u1;
wire QN_u2;
wire QN_u3;
wire QN_u4;
wire u2_Q1;
wire [9:0] u1_Qx;
wire [9:0] u2_Qx;
wire CO;
wire u2_clk;
wire u2_decimal_counter_MR;

//reg OUTPUT_A = 1'b1;

reg high = 1'b1;
reg low = 1'b0;

//D类触发器1
data_flip_flop u1_data_flip_flop(
    .RST(SYS_RST),
    .D(QN_u1), //数据输入
    .CLK(SYS_CLK), //时钟(上升沿有效)
    .SD(high), //复位(低电平有效),Q置1
    .RD(u2_Q1), //复位(低电平有效),Q置0
    .Q(OUTPUT_D), //输出端
    .QN(QN_u1) //输出端取反
);
//D类触发器2
data_flip_flop u2_data_flip_flop(
    .RST(SYS_RST),
    .D(QN_u2), //数据输入
    .CLK(QN_u1), //时钟(上升沿有效)
    .SD(high), //复位(低电平有效),Q置1
    .RD(u2_Q1), //复位(低电平有效),Q置0
    .Q(OUTPUT_C), //输出端
    .QN(QN_u2) //输出端取反
);
//D类触发器3
data_flip_flop u3_data_flip_flop(
    .RST(SYS_RST),
    .D(QN_u3), //数据输入
    .CLK(QN_u2), //时钟(上升沿有效)
    .SD(high), //复位(低电平有效),Q置1
    .RD(u2_Q1), //复位(低电平有效),Q置0
    .Q(OUTPUT_B), //输出端
    .QN(QN_u3) //输出端取反
);
//D类触发器4
data_flip_flop u4_data_flip_flop(
    .RST(SYS_RST),
    .D(QN_u4), //数据输入
    .CLK(QN_u3), //时钟(上升沿有效)
    .SD(high), //复位(低电平有效),Q置1
    .RD(u2_Q1), //复位(低电平有效),Q置0
    .Q(OUTPUT_A), //输出端
    .QN(QN_u4) //输出端取反
);

//十进制计数器CD4017-1
decimal_counter u1_decimal_counter(
    .Qx(u1_Qx), //计数脉冲输出端
    .CO(CO), //进位脉冲输出端
    .CLK(SYS_CLK), //时钟输入端
    .E(low), //INH计数使能端(低电平有效)
    .MR(u2_decimal_counter_MR) //CR计数清除端(低电平有效)
);

//十进制计数器CD4017-2
decimal_counter u2_decimal_counter(
    .Qx(u2_Qx), //计数脉冲输出端
    .CO(CO), //进位脉冲输出端
    .CLK(u2_clk), //时钟输入端
    .E(low), //INH计数使能端(低电平有效)
    .MR(u2_decimal_counter_MR) //CR计数清除端(低电平有效)
);

decimal_counter_converter_u1 u1_decimal_counter_converter_u1(
    .CLK(SYS_CLK),
    .Qx(u1_Qx),
    .Q9(u2_clk)
);

decimal_counter_converter_u2 u1_decimal_counter_converter_u2(
    .RST(SYS_RST),
    .CLK(SYS_CLK),
    .Qx(u2_Qx),
    .Q1(u2_Q1),
    .Decimal_Counter_RST(u2_decimal_counter_MR)
);

endmodule

RTL视图

在这里插入图片描述

RTL仿真结果

在这里插入图片描述

门级仿真结果

在这里插入图片描述

实物运行效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Share

xddcore

xddcore www.github.com/xddcore

You may also like...

发表回复

您的电子邮箱地址不会被公开。