基础数字电路的Verilog写法
Verilog是硬件描述电路,我对此一直稀里糊涂,于是将锆石科技开发板附带的的一些基础数字电路Verilog程序整理记录下来,并且查看他们的RTL视图,总算有点理解了。
1.基本运算符
module Example_Operation
(
input [:] a ,
input [:] b ,
input [:] c , output [:] c1 ,
output [:] c2 ,
output [:] c3 ,
output [:] c4 ,
output [:] c5 ,
output [:] d1 ,
output [:] d2 ,
output [:] d3 ,
output [:] d4 ,
output [:] e1 ,
output [:] e2 ,
output [:] e3 ,
output [:] f1 ,
output [:] f2 ,
output [:] d11 ,
output [:] c11 ,
output [:] c22 ,
output [:] c33 ,
output [:] c44 ,
output [:] c55 ,
output [:] c66 ,
output [:] e11 ,
output [:] e22 ,
output [:] f11 ,
output [:] f22
); //== waveform1 算数运算符
//======================================================================
assign c1 = a + b; //加
assign c2 = a - b; //减
assign c3 = a * b; //乘
assign c4 = a / b; //除
assign c5 = a % b; //求余 //== waveform2 关系运算符
//======================================================================
assign d1 = a > b; //大于
assign d2 = a < b; //小于
assign d3 = a >= b; //大于等于
assign d4 = a <= b; //小于等于 //== waveform3 逻辑运算符
//======================================================================
assign e1 = !a; //非
assign e2 = a && b; //与
assign e3 = a || b; //或 //== waveform4 逻辑等式运算符
//======================================================================
assign f1 = a == b; //判断相等
assign f2 = a != b; //判断不等 //== waveform5 三目条件运算符
//======================================================================
assign d11 = a ? b : c; //a为真,则d11 = b
//a为假,则d11 = c //== waveform6 位运算符
//======================================================================
assign c11 = ~a; //取反
assign c22 = a & b; //按位与
assign c33 = a | b; //按位或
assign c44 = a ^ b; //按位异或
assign c55 = a ~^ b; //按位同或
assign c66 = a ^~ b; //按位同或 //== waveform7 移位运算符
//======================================================================
assign e11 = a << b; //左移
assign e22 = a >> b; //右移 //== waveform8 位拼接运算符
//======================================================================
assign f11 = {a , b}; //拼接a和b,a和b位宽均为4,f11位宽为8
assign f22 = {'d2{b}}; //拼接b低2位 endmodule
2.三人表决器 --- 结构描述方式
module Example_Structure
(
input A , //模块的输入端口A
input B , //模块的输入端口B
input C , //模块的输入端口C
output L //模块的输出端口L
); //== 信号定义
//======================================================================
wire AB,BC,AC; //内部信号声明AB,BC,AC and U1(AB,A,B); //与门(A,B信号进入)(A与B信号即AB输出)
and U2(BC,B,C); //与门 同上
and U3(AC,A,C); //与门 同上 or U4(L,AB,BC,AC); //或门 同上 endmodule

3.三人表决器 --- 数据流描述方式
module Example_Dataflow
(
input A , //模块的输入端口A
input B , //模块的输入端口B
input C , //模块的输入端口C
output L //模块的输出端口L
); assign L = ((!A) & B & C) | (A & (!B) & C) | (A & B & (!C)) | (A & B & C); endmodule

4.三人表决器 --- 行为描述方式
module Example_Behavior
(
input A , //模块的输入端口A
input B , //模块的输入端口B
input C , //模块的输入端口C
output reg L //模块的输出端口L
); always @(A,C,B)begin //敏感列表只需要A、B、C,也可以写成always @(*)
case({A,B,C}) //注意{A,B,C}是位拼接,合成一条总线
'b000: L = 1'b0;
'b001: L = 1'b0;
'b010: L = 1'b0;
'b011: L = 1'b1;
'b100: L = 1'b0;
'b101: L = 1'b1;
'b110: L = 1'b1;
'b111: L = 1'b1;
default:L = 'bx; //default不要省略
endcase
end endmodule

5.模块化设计实现半加器
module Example_Module
(
input a ,
input b ,
output s ,
output c
); //== 实例化 与门
//======================================================================
Example_yumen yumen_module
(
.yumen_a(a),
.yumen_b(b),
.yumen_c(c)
); //== 实例化 异或
//======================================================================
Example_yihuo yihuo_module
(
.yihuo_a(a),
.yihuo_b(b),
.yihuo_s(s)
); endmodule
Top
module Example_yihuo
(
input yihuo_a ,
input yihuo_b ,
output yihuo_s
); assign yihuo_s = yihuo_a ^ yihuo_b; endmodule
Yihuo
module Example_yumen
(
input yumen_a ,
input yumen_b ,
output yumen_c
); assign yumen_c = yumen_a && yumen_b; endmodule
Yumen

6.8-1数据选择器
module Digital_Selector
(
input D0 ,
input D1 ,
input D2 ,
input D3 ,
input D4 ,
input D5 ,
input D6 ,
input D7 ,
input [ :] A ,
output reg [ :] Y
); always @(*)begin
case(A)
'b000 : Y = D0;
'b001 : Y = D1;
'b010 : Y = D2;
'b011 : Y = D3;
'b100 : Y = D4;
'b101 : Y = D5;
'b110 : Y = D6;
'b111 : Y = D7;
default: Y = 'b0;
endcase
end endmodule

7.8-3编码器
module Digital_Encoder
(
input [ :] I ,
output reg [ :] A
); //== case判断I,8位数转为3位数
//======================================================================
always @(*)begin
case(I)
'b0000_0001 : A = 3'b000;
'b0000_0010 : A = 3'b001;
'b0000_0100 : A = 3'b010;
'b0000_1000 : A = 3'b011;
'b0001_0000 : A = 3'b100;
'b0010_0000 : A = 3'b101;
'b0100_0000 : A = 3'b110;
'b1000_0000 : A = 3'b111;
default: A = 'b000;
endcase
end /*
//== if...else优先级写法,优先级从上到下
//======================================================================
always @(*)begin
if(I[7] == 1'b0) A = 3'b000;
else if(I[6] == 1'b0) A = 3'b001;
else if(I[5] == 1'b0) A = 3'b010;
else if(I[4] == 1'b0) A = 3'b011;
else if(I[3] == 1'b0) A = 3'b100;
else if(I[2] == 1'b0) A = 3'b101;
else if(I[1] == 1'b0) A = 3'b110;
else if(I[0] == 1'b0) A = 3'b111;
else A = 3'b000;
end
*/ endmodule


8.3-8译码器
module Digital_Decoder
(
input [ :] A ,
output reg [ :] I
); always @(*)begin
case(A)
'b000 : I = 8'b01111111;
'b001 : I = 8'b10111111;
'b010 : I = 8'b11011111;
'b011 : I = 8'b11101111;
'b100 : I = 8'b11110111;
'b101 : I = 8'b11111011;
'b110 : I = 8'b11111101;
'b111 : I = 8'b11111110;
default: I = 'b11111111;
endcase
end endmodule

9.D触发器
module Digital_Data_Flip_Flop
(
input clk ,
input rst_n ,
input D ,
output reg Q
); always @(posedge clk or negedge rst_n)begin
if(!rst_n)
Q <= 'b0;
else
Q <= D;
end endmodule

10.4bit移位寄存器
module Digital_Shift_Reg
(
input clk ,
input rst_n ,
input data_in ,
input data_en ,
output reg [ :] data_out ,
output reg [ :] data_out_n
); //== 时序逻辑,寄存data_out_n的值,所以看起来比data_out_n慢一拍
//======================================================================
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
data_out <= 'b0;
else
data_out <= data_out_n;
end //== 组合逻辑,不断移位
//======================================================================
always @(*)begin
if(data_en)
data_out_n = {data_out[:],data_in};
else
data_out_n = data_out;
end /*----------------------------------------------------------------------
--补充:如果要实现循环右移,则写成[data_in,data_out[3:1]]
----------------------------------------------------------------------*/ endmodule

11.反馈回环的正误解析
//== 错误写法:data_out既是条件又是结果
//======================================================================
module Example_Feedback
(
input data_in1 ,
input data_in2 ,
output data_out
);
//data_out是最终结果,可又是形成条件
assign data_out = (data_in2) ? data_in1 : (~data_out | data_in1); endmodule /*
//== 正确写法:用data_out_r寄存一下,再给data_out
//======================================================================
module Example_Feedback
(
input clk ,
input rst_n ,
input data_in1 ,
input data_in2 ,
output data_out
); //信号定义
reg data_out_r ; //时序逻辑,寄存结果
always @ (posedge clk or negedge rst_n)
begin
if(!rst_n)
data_out_r <= 1'b0;
else
data_out_r <= (data_in2) ? (data_in1) : (~data_out_r | data_in1);
end //寄存后的结果再输出
assign data_out = data_out_r; endmodule
*/


12.阻塞赋值和非阻塞赋值
module Example_Block
(
input clk ,
input block_in ,
output block_out1 ,
output block_out2 ,
output no_block_out1 ,
output no_block_out2
); //block模块例化
block block_init
(
.clk (clk ),
.block_in (block_in ),
.block_out1 (block_out1 ),
.block_out2 (block_out2 )
); //no_block模块例化
no_block no_block_init
(
.clk (clk ),
.no_block_in (block_in ),
.no_block_out1 (no_block_out1 ),
.no_block_out2 (no_block_out2 )
); endmodule
Top
module block
(
input clk ,
input block_in ,
output reg block_out1 ,
output reg block_out2
); always @(posedge clk)begin
block_out1 = block_in;
block_out2 = block_out1;
end endmodule
Block
module no_block
(
input clk ,
input no_block_in ,
output reg no_block_out1 ,
output reg no_block_out2
); always @(posedge clk)begin
no_block_out1 <= no_block_in;
no_block_out2 <= no_block_out1;
end endmodule
no_Block


这些基础数字电路的Verilog描述应该非常熟悉,才能够为后面的学习打下扎实的基础。
参考资料:[1]锆石科技FPGA教程
基础数字电路的Verilog写法的更多相关文章
- 状态机的Verilog写法
“硬件设计很讲究并行设计思想,虽然用Verilog描述的电路大都是并行实现的,但是对于实际的工程应用,往往需要让硬件来实现一些具有一定顺序的工作,这就要用到状态机思想.什么是状态机呢?简单的说,就是通 ...
- 计数器的Verilog写法
计数器是非常基本的使用,没有计数器就无法处理时序.我在学习时发现市面上有几种不同的计数器写法,非常有趣,在此记录下来: 一.时序逻辑和组合逻辑彻底分开(by锆石科技FPGA教程) 1.代码 //=== ...
- 6-最基础的服务-es6写法
创建server.js 'use strict'; //http模块 var http = require('http'); //封装的方法 var handlers = require('./han ...
- JavaWeb基础—项目名的写法
${pageContext.request.contextPath} //jsp中 request.getContextPath() //Servlet中 两者获取到的都是"/项目名称&qu ...
- 【第一季】CH04_FPGA设计Verilog基础(一)Enter a post title
[第一季]CH04_FPGA设计Verilog基础(一) 4.1 Verilog HDL 代码规范 u 项目构架设计 项目的构架用于团队的沟通,以及项目设计的全局把控 u 接口时序设计规范 模块和模块 ...
- 不可综合的verilog语句分析
前半部分转自http://www.cnblogs.com/Mrseven/articles/2247657.html,后半部分为自己测试结果. 基础知识:verilog 不可综合语句 (1)所有综合工 ...
- verilog 不可综合语句
转自http://bbs.ednchina.com/BLOG_ARTICLE_1770084.HTM 基础知识:verilog 不可综合语句 (1)所有综合工具都支持的结构:always,assig ...
- 关于CPU Cache -- 程序员需要知道的那些事
本文将介绍一些作为程序猿或者IT从业者应该知道的CPU Cache相关的知识.本章从"为什么会有CPU Cache","CPU Cache的大致设计架构",&q ...
- 关于CPU Cache:程序猿需要知道的那些
天下没有免费的午餐,本文转载于:http://cenalulu.github.io/linux/all-about-cpu-cache/ 先来看一张本文所有概念的一个思维导图: 为什么要有CPU Ca ...
随机推荐
- CF888G 【Xor-MST】
妙妙题-- 看到\(MST\),想到\(Kruskal\),看到异或,想到\(Trie\) 首先我们模拟一下\(Kruskal\)的流程:找到最小边,如果联通就忽略,未联通就加边 我们把所有点权值加入 ...
- JavaScript高级程序编程(三)
2017-06-24 更新 北京连续三天下雨啦 乘性操作符 1.ECMA中定义了三种操作符,乘法 除法 和求模 并与其他语言相应操作符相同,再计算之前如果不是数值,会先去调用number()方法转 ...
- idea 导入 eclipse java ee 项目,并使用 tomcat 7 部署运行
1.导入java ee项目.直接open 2.导入jar依赖 3.修改编译的目录 4.修改tomcat目录 5.tomcat添加目录 请注意classes单词 D:\project\xxxxxx\We ...
- 「ZJOI2019」Minmax搜索
传送门 Solution 叶子节点的变化区间是连续的,可得知非叶子节点的权值变化区间也是连续的 由此可知,\(W\)的变化值的可行域也是连续的,所以只需要看它能否变为\(W+1\)或\(W-1\) 对 ...
- windows环境搭建dubbo服务
windows环境搭建dubbo服务 1:首先需要下载dubbo的注册中心 zookeeper zookeeper注册中心下载地址链接:http://mirror.bit.edu.cn/apache/ ...
- Stringbuilde方法的用法以及其作用
Stringbuilde的方法有以下几种(常用的):(java中的语法) 在程序开发过程中,我们常常碰到字符串连接的情况,方便和直接的方式是通过"+"符号来实现,但是这种方式达到目 ...
- hdu1002 A + B Problem II[大数加法]
目录 题目地址 题干 代码和解释 参考 题目地址 hdu1002 题干 代码和解释 由题意这是一个涉及到大数的加法问题.去看了一眼大数加法的方法感觉头很大,然后突然发现Java可以流氓解决大数问题,毅 ...
- MySQL事务部分回滚-回滚到指定保存点
我们可以在mysql事务处理过程中定义保存点(SAVEPOINT),然后回滚到指定的保存点前的状态. 定义保存点,以及回滚到指定保存点前状态的语法如下. 定义保存点---SAVEPOINT 保存点名; ...
- Linux环境下查看历史操作命令及清除方法(history -c)
在Linux环境中可以通过方向键的上下按键查看近期键入的命令.但这种方法只能一个一个的查看,其实系统提供了查看所有历史命令的方法. 在终端中输入以下命令查看所有命令: history [root@te ...
- python的subprocess模块介绍
一.subprocess以及常用的封装函数运行python的时候,我们都是在创建并运行一个进程.像Linux进程那样,一个进程可以fork一个子进程,并让这个子进程exec另外一个程序.在Python ...