module ZephRay;

今朝有鱼今朝摸

Category

  • 摄影
  • 玩机
  • 硬件坑
  • 翻译
  • 软件坑
  • 随记

Tags

  • LCD
  • 点屏
  • 单片机
  • 贴图
  • 计算器
  • 事
  • FPGA
  • 摄影
  • STM32
  • Verilog
  • 古董
  • 测评
  • 笔记本
  • 改造
  • 移植
  • Linux
  • ARM
  • 树莓派
  • 小动物
  • nspire
  • 教程
  • GameBoy
  • 景
  • LED
  • 项目
  • EPD
  • 3DS
  • 晒机
  • HP
  • IBM
  • SDL
  • ThinkPad
  • 82ES
  • Kindle
  • Minecraft
  • Assembly
  • 手办
  • Chiptune
  • 仙剑奇侠传
  • 花
  • 演讲
  • NDSL
  • Nikon

Recent replies

  • Khiemmy 发表于「On the way to overclock the TI nspire CX II calculator」
  • critor 发表于「On the way to overclock the TI nspire CX II calculator」
  • ZephRay 发表于「On the way to overclock the TI nspire CX II calculator」
  • critor 发表于「On the way to overclock the TI nspire CX II calculator」
  • Rise 发表于「写给玩家的FPGA入门指南(6)——Verilog(下)」
  • imbushuo 发表于「About Me」
  • 070 发表于「古董电脑选型」
  • Thermit 发表于「About Me」
  • 盛崖鱼 发表于「About Me」
  • Wenting Zhang 发表于「About Me」

My

RSS (中文优先)
RSS (English preferred)

坑 / Projects
关于我 / About
简历 / CV
破烂采购计划 / Craplist
古董电脑选型
SM83(GB CPU)指令编码
Linux PI 1M位跑分
Coremark跑分
音质参考

淘宝杂货铺
Bilibili空间
GitHub

Links

cnVintage古董电子论坛
cnCalc计算器论坛

Keshuai Xu
家骅的锦绣谷
>Lithia's Core
ntzyz's space
丘丘塔台
tonoko.moe
kasora's blog
447f.Misaka
paizhang.info
spinmry实验室
Hikari Calyx Tech.
春上冰月的博客
初音没有来
FindHao
Test2g
Shell Bin
LEAFER x LAB
标签:教程

写给玩家的FPGA入门指南(6)——Verilog(下)

2019 年 2 月 24 日分类:硬件坑#FPGA#Verilog#教程

本期,我们将继续讲解之前没有讲完的Verilog代码。上一期的教程已经介绍了Verilog最核心的一些操作,本期则将介绍一些有用的其它操作,他们最终也可以用核心的操作代码表示出来,但是通常而言编写起来更为简便。本期同样会介绍仿真工具的使用,在开发过程中非常有用。不过在开始新的内容之前,先来讲讲上一次留的作业。

上期练习

上期留了一个作业,就是实现第五期里面讲过的状态机。这里首先复述一下第五期的状态机:假设一个贩卖机,只卖矿泉水,价格定为2元,只接受1元硬币或者5角硬币,多不找零,设计一个状态机来描述它的行为。这个机器的话,它有两个输入,投入5角或者投入1元;以及一个输出,是否已经付了足够多的钱。

如同之前一样,假设表示投入5角硬币的信号叫a,表示投入1元硬币的信号叫b,输出是否已经付够钱的信号叫c。同时定义这个系统有S0-S4一共5个状态,分别表示当时已经投入了0、0.5、1、1.5和2元。

要用Verilog来实现这个状态,第一步肯定是先写一个整体的模块框架,再往里面加入东西。于是参考上期的声明module的方法,先写下如下的代码:

module vending(
    input clk,
    input rst,
    input a,
    input b,
    output c);

endmodule

上面的代码定义了一个叫vending的模块,有四个输入,clk、rst、a和b,一个输出c,主体没有内容。clk提供时钟,rst提供复位。首先来考虑输出吧。状态机的输出是由当前状态决定的,所以需要有一个变量(触发器)来保存当前的状态,比如叫做state:

reg [2:0] state;

有了state之后就可以描述输出的逻辑了。一种方法是直接用第五期的逻辑表达式:

assign c = state[2] && !state[1] && !state[0];
MORE

写给玩家的FPGA入门指南(5)——Verilog(上)

2019 年 1 月 7 日分类:硬件坑#FPGA#Verilog#教程

首先,恭喜大家,一直跟到了这个教程的第五期。如之前所说,从本期开始,我们将正式开始使用Verilog给FPGA写代码。而要写的东西,这是第2-4期里面介绍过的组合逻辑,时序逻辑和状态机。而Verilog也将会是在这之后用于描述各种硬件的语言。

其实读Verilog代码本身并不复杂,有软件编程经验的人就不难理解代码的含义,毕竟其语法和C语言很接近;但是写Verilog代码,就是另外一回事了。Verilog里面有很多和C接近的概念和语句,比如赋值,比如if-else,比如for循环,等等。但是Verilog的目标结果,逻辑门,却又和C的目标结果,程序,太不一样了。他们确实某种程度上是接近的语言,但是语言里有接近的东西并不表示他们就能实现接近的功能。或者反过来,想要实现同样的功能,未必会使用接近的方法。所以说,学习Verilog最好的捷径就是不要走捷径,从数字电路开始学习,而并非一开始就学习代码,以至于被代码所迷惑。

Verilog程序模块

Verilog程序如同其它的编程语言程序一样,有它特定的源文件格式。Verilog的源代码后缀名为.v,每一个Verilog文件都是一个Verilog模块,各位可以类比为编程语言中的函数。基本格式如下:

module 模块名(模块输入输出信号);
    模块内容
endmodule

其中这个模块名通常需要和对应的文件名相同,同一个文件只定义一个模块,比如adder.v里就应该只定义一个叫adder的模块。这个要求和Java对类的要求很相似。

输入输出信号则是接近一个函数的返回值和参数,只不过在Verilog里并不把参数和返回值放到不同的地方定义,而是都写在一起。所有的参数或者返回值,最终都只是导线而已。而导线根据驱动信号的方向,可以有输入和输出区别。至于需要多少个输入多少个输出,那就取决于具体的程序了。

模块内容则是模块内部的逻辑,也许有代码块(always),也许只是一些简单的接线(assign)。不过别忘了,一切最后都会回归到硬件。

最后说说模块的实例化,或者说调用。如前面所说,模块类似于软件编程语言里面的函数,它也确实有对应的函数名,参数,返回值等等类似的概念。那么要使用这个“函数”,自然也就需要一种调用的方法。只不过,Verilog里的调用,并不是像编程语言一样在特定位置执行特定代码(毕竟本身就没有“执行代码”这种操作),而是新复制一份这个模块所表示的硬件,然后连接对应的导线。这一点在参数的定义时其实也就有所体现,定义的输入输出并非是变量,而是导线, 也就是说,传递的内容并不是数值,而是连接。一旦连接被确定,传输就是时时进行的(因为线被连接上了)。这个和编程语言里的调用非常不一样,所以务必进行区分。具体的例子我们之后就会提到。

MORE

写给玩家的FPGA入门指南(4)——状态机

2018 年 12 月 10 日分类:硬件坑#FPGA#教程#Verilog

大家好,欢迎回到FPGA教程的第四期。说是FPGA教程,结果一直在和大家讲数字电路的事情,但是毕竟数字电路是一切的基础,如果不理解数字电路,也许一开始玩FPGA不会有太大问题,但是越到后面就会觉得越玄。所以拥有良好的基础还是相当必要的。不过好消息是,本期就是数字电路基础的最后一期了。下一期开始就可以开始写Verilog玩FPGA了。

什么是状态机

其实各位可能之前已经听说过了状态机这个名词。状态机是个软硬件中都非常常用的设计。其实更像是一种设计模板,把需要实现的功能,划分成状态,然后套进状态机的模板中,最后实现这个状态机。那为什么要这么麻烦套成状态机再实现状态机,而不是直接实现这个电路呢?原因其实也很简单,一旦逻辑复杂到一定程度,“直接实现”会变得很难管理,而最后为了提高可维护性通常还是得引入状态机的设计。这样还不如一开始就做状态机呢。

状态机,顾名思义,必然是和 状态 相关的。状态机的主要思想就是,把一个机器的运行情况人为划分成很多不同的状态,而机器的输出,根据当前所处的状态来决定,而机器的输入则会影响到机器之后的状态。进一步到具体机器的设计,其实无非也就是要回答两个问题:

  1. 在什么状态下要做什么事情

  2. 怎么样会导致状态发生改变

比如最简单的例子,一盏灯,按一下会亮,再按一下会灭。这个机器就可以定义为有两个状态,一个是灯亮,一个是灯灭。回答第一个问题,什么状态下要做什么事情:灯亮的状态下,输出亮;灯灭的状态下,输出灭。回答第二个问题,怎么样会导致状态发生改变:灯亮的状态下,如果按键按下,就进入灯灭的状态;灯灭的状态下,如果按键按下,就进入灯亮的状态。无论何种状态下,如果没有按键按下,则停留在当前的状态。如果画成状态图的话,大致如下:

1551046828638-4-1.png

MORE

写给玩家的FPGA入门指南(3)——时序逻辑

2018 年 11 月 5 日分类:硬件坑#Verilog#FPGA#教程

上期教程中介绍了组合逻辑的使用,而本期教程则要来讲讲时序逻辑。

那么当然,第一个要回答的问题就是,组合逻辑电路和时序逻辑电路有什么区别。如果重新考虑之前做过的电路,不难发现一个特点,这些电路都是给定输入,得到输出。只要输入是一定的,输出也就是一定的。所有影响输出的因素只是输入而已。听起来很自然,没有什么问题对吧?甚至可能还觉得奇怪,如果我给定了输出,但是却不能确定输出,那不是乱套了吗?考虑这么一个需求。还是有一盏灯,有一个按钮,现在需要,按下按键,灯点亮,然后一直保持点亮,再按下按键,灯关闭,并保持关闭。不难看出,单独给定输入状态(按键按下或者没有按下)根本没法知道灯是开着还是关着,也就是输出不单单取决于当前输入,还取决于当前的状态。换句话说,电路有了自己的记忆。而在分析时,除了要考虑当前发生的事情,还需要考虑之前发生过的事情, 多了时间维度。这种电路被称为时序逻辑电路。

锁存器与触发器

记忆这事在单片机或者任何软件编程环境里都好说啊,无非是一个变量的事情。但是如果说回到电路角度,应该怎么解决这个问题呢?引入新的逻辑门,比如说 存储门什么的东西?其实完全不用,只要用之前在组合逻辑时用过的那些东西就可以做出能够存储状态的电路哦。原理图如下

1551044954929-3-1.png

看着有些奇怪是不是,这种电路应该怎么分析呢?因为一眼看过去似乎找不到什么输入,只有一个输出Q。不妨考虑下其中任意一条线为高或低,随后计算出来其它所有线的电平,发现没有出现逻辑上的冲突,也就是只要保持通电,这些电平就会一直保持这个状态。但是如果这时,由于外部的信号,改变了其中任意一条线的电平,所有的电平都会变化,并一直保持新的状态。所以呢,这也就是能够存储1个bit的电路了。

MORE

写给玩家的FPGA入门指南(2)——组合逻辑

2018 年 10 月 7 日分类:硬件坑#FPGA#Verilog#教程

在进行了两期的背景介绍后,本期也是终于是进入正题了。如果你之前有了解过数字电路,大概就听说过数字电路大致可以分为组合逻辑电路和时序逻辑电路,而大部分的电路都是这两者的结合。本期所要介绍的也就是这其中的前者:组合逻辑。顺便,上期之后,大概部分玩家购买的74芯片或者FPGA开发板也已经到货了吧?本期也会附带关于如何用74或者FPGA实现这些实验的说明。   第一个例子还是从第一期举过的例子开始好了。想要设计一个电路,里面有两个开关和一个灯泡,希望实现两个开关任意一个打开的时候灯泡点亮。当然,一个显而易见的解决方案就是把两个开关并联,如下图所示:

1540159699475-1.png

但是如果我们用像一般考虑单片机电路一样的思路去考虑,那么就可以把两个开关看作是两个输入口,而灯泡是一个输出口,那么这个电路就会变成这样:

1540159701655-2.png

而这个盒子里面所包括的就是需要实现的电路。这个电路可以是一块74,也可以是一块单片机,或者只是像图1一样简单的连接起来而已。这里就来考虑下,如果要用单片机来实现要怎么做吧。很简单,一句if语句的事情,直接翻译要求,if ((a == 1)||(b == 1)) c = 1; else c = 0; 可以看见逻辑运算已经出现了,输入1为高或者输入2为高时,输出1为高,否则输出1为低,这样就是这个简单例子的逻辑。另外等于1 可以省略,就变成了if (a || b) c = 1; else c = 0;,再考虑到因为逻辑运算的结果本身就是1或者0,这里甚至不需要if,只需要 c = (a || b) 即可。 只有一个简单的“或”运算(||, OR)的关系,如果要用图示描述出来的话:

MORE
  • «
  • 1
  • 2
  • »
Copyright © 2009-2019 Wenting Zhang. All rights reserved.
Unless otherwise noted, content on this blog is licensed under CC BY-SA 4.0.