基础数字电路的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 ...
随机推荐
- WinDbg常用命令系列---显示加载的模块列表lm
lm (List Loaded Modules) lm命令显示指定的加载模块.输出包括模块的状态和路径. lmOptions [a Address] [m Pattern | M Pattern] 参 ...
- rust-vmm 学习(二)
eventfd virtio中,guest和vhost通过evnetfd通知对方,见(Virtio ring and virtio-net). REF: Qemu-kvm的ioeventfd创建与触发 ...
- bash循环得到日期目录
#!/bin/bash today=$(date "+%Y%m%d") echo 'today is :'${today} single_input="raw_data/ ...
- Java基础教程(全代码解析)
字面量: 整数字面量为整型(int) 小数字面量为双精度浮点型(double) 数据类型: byte short int long float double 接下来代码展示理解 public clas ...
- GoCN每日新闻(2019-10-03)
GoCN每日新闻(2019-10-03) 国庆专辑:GopherChina祝大家国庆节快乐 GoCN每日新闻(2019-10-03) 1. 垃圾回收器如何监控你的应用程序 https://medium ...
- Pytest权威教程(官方教程翻译)
Pytest权威教程01-安装及入门 Pytest权威教程02-Pytest 使用及调用方法 Pytest权威教程03-原有TestSuite的执行方法 Pytest权威教程04-断言的编写和报告 P ...
- hive select 出现问题 SemanticException
由于把hadoop的以下配置项 <property> <name>fs.defaultFS</name> <value>hdfs://localhost ...
- 软件工程 “校园汇” 个人IDEA竞选分析与总结
IDEA竞选 19/10/8软件工程课上举行了一次IDEA竞选: 我的竞选IDEA是"校友汇",大学生的在线活动中心. 投票结果: 可以看到,校友会(汇)IDEA竞选结果十分惨淡, ...
- 创业小记:ALL IN才是迈出创业第一步的关键
对于创业而言,能卖出这创业第一步的,大多都经过了长期反复的心理拷问与折磨. 因为当你迈出创业的那一步,你可能需要面对的是毫无收入保障的生活,以及后果自负的结局. ALL IN才是迈出创业第一步的关键( ...
- Java基础 while 简单示例
JDK :OpenJDK-11 OS :CentOS 7.6.1810 IDE :Eclipse 2019‑03 typesetting :Markdown code ...