【HDLBits 刷题 4】Verilog Language(4)Procedures 和 More Verilog Features 部分

2023-11-04

目录

写在前面

Procedures

Alwaysblock1

Alwaysblock2

Always if

Always if2

Always case

Always case2

Always casez

Always nolatches

More Verilog Features

Conditional

Reduction

Gates100

Vector100r

Popcount255

Adder100i

Bcdadd100


写在前面

本篇博客对 Verilog Language 剩余两个部分的题目写完,首先对题干先读懂是关键,然后思考如何实现并验证,这里采用先对题目解读,也就是要让我们干什么,然后直接给出答案。


Procedures

Alwaysblock1

分别用 assign 语句和 always @(*) 块语句实现与门操作。

module top_module(
    input        a, 
    input        b,
    output wire  out_assign,
    output reg   out_alwaysblock
);

assign out_assign = a & b;

always @(*) begin
	out_alwaysblock = a & b;
end

endmodule

Alwaysblock2

连续赋值(assign x = y;)。不能在 always 块中使用。
过程阻塞赋值:(x = y;)。只能在过程中使用。
过程非阻塞赋值:(x <= y;)。只能在过程中使用。
在组合 always 块中,使用阻塞赋值。
在时序 always 块中,使用非阻塞赋值。

module top_module(
    input        clk,
    input        a,
    input        b,
    output wire  out_assign,
    output reg   out_always_comb,
    output reg   out_always_ff  
);

assign out_assign = a ^ b;

always @(*) begin
	out_always_comb = a ^ b;
end

always @(posedge clk) begin
	out_always_ff <= a ^ b;
end

endmodule

Always if

if 语句通常创建一个 2 对 1 多路复用器,如果条件为 ture,则选择一个输入,如果条件为 false,则选择另一个输入。这等效于使用带有条件运算符的连续赋值:       
assign out = (condition) ? x : y;
构建一个在 a 和 b 之间进行选择的 2 对 1 多路复用器。如果sel_b1和sel_b2都为真,请选择 b。否则,请选择 a。执行相同的操作两次,分别使用赋值语句和过程 if 语句。

module top_module(
    input        a,
    input        b,
    input        sel_b1,
    input        sel_b2,
    output wire  out_assign,
    output reg   out_always   
); 

assign out_assign = (sel_b1 & sel_b2) ? b : a;

always @(*) begin
	if (sel_b1 & sel_b2) begin
		out_always = b;
	end
	else begin
		out_always = a;
	end
end

endmodule

Always if2

学习如何避免产生 latch, 比如在 always 块中所列举的情况没有完全,会出现你没有列举的情况时,那输出会是什么呢?Verilog的答案是:保持输出不变。这种“保持输出不变”的行为意味着需要记住当前状态,从而产生latch。组合逻辑不能保存任何状态。组合电路必须在所有条件下为所有输出分配一个值。这通常意味着始终需要为输出分配 else 子句或默认值。

module top_module (
    input      cpu_overheated,
    output reg shut_off_computer,
    input      arrived,
    input      gas_tank_empty,
    output reg keep_driving  ); //

    always @(*) begin
        if (cpu_overheated) begin
            shut_off_computer = 1;
        end
        else begin
           	shut_off_computer = 0;
        end   
    end

    always @(*) begin
        if (~arrived) begin
            keep_driving = ~gas_tank_empty;	
        end
        else begin
        	keep_driving = 0;
        end
    end

endmodule

Always case

case语句的练习。case 语句以 case 开头,每个“case 项”都以冒号结尾。
每个事例项只能执行一条语句。这意味着,如果需要多个语句,则必须使用begin结束。允许重复(和部分重叠)案例项目。使用第一个匹配的。
在本练习中,创建一个 6 对 1 多路复用器。当 sel 介于 0 和 5 之间时,选择相应的数据输入。否则,输出 0。数据输入和输出均为4位宽。

module top_module ( 
    input      [2:0]   sel, 
    input      [3:0]   data0,
    input      [3:0]   data1,
    input      [3:0]   data2,
    input      [3:0]   data3,
    input      [3:0]   data4,
    input      [3:0]   data5,
    output reg [3:0]   out   
);

    always @(*) begin  
        case(sel)
        	0: out = data0;
        	1: out = data1;
        	2: out = data2;
        	3: out = data3;
        	4: out = data4;
        	5: out = data5;
      default: out = 0;
        endcase
    end

endmodule

Always case2

优先级编码器是一种组合电路,当给定输入位矢量时,输出矢量中第一个1位的位置。例如,给定输入 8'b100 1 0000 的 8 位优先级编码器将输出 3'd4,因为 bit[4] 是第一个高位。构建 4 位优先级编码器。对于此问题,如果输入位均为零,则输出为零。请注意,4 位数字有 16 种可能的组合。

module top_module (
    input      [3:0]  in,
    output reg [1:0]  pos  
);

always @(*) begin
	case(in)
		4'b0000: pos = 0;
		4'b0001: pos = 0;
		4'b0010: pos = 1;
		4'b0100: pos = 2;
		4'b1000: pos = 3;
		4'b0011: pos = 0;
		4'b0110: pos = 1;
		4'b1100: pos = 2;
		4'b0101: pos = 0;
		4'b1010: pos = 1;
		4'b1001: pos = 0;
		4'b0111: pos = 0;
		4'b1110: pos = 1;
		4'b1011: pos = 0;
		4'b1101: pos = 0;
		4'b1111: pos = 0;
	endcase
end

endmodule

Always casez

case 语句就像是按顺序检查每个情况,这是一个很大的组合逻辑函数。请注意,某些输入(例如,4'b1111)将如何匹配多个事例项。选择第一个匹配项(因此 4'b1111 匹配第一个项目,out = 0,但后面的任何一个都不匹配)。还有一个类似的案例,它将x和z视为不在乎。我看不出在casez上使用它有多大意义。数字 ? 是 z 的同义词。所以 2'bz0 与 2'b?0 相同。

module top_module (
    input      [7:0]  in,
    output reg [2:0]  pos  
);

always @(*) begin
	casez(in)
		8'bzzzzzzz1: pos = 0;   //z表示不在乎这个是什么值。只需要满足后面位的情况
		8'bzzzzzz10: pos = 1;
		8'bzzzzz100: pos = 2;
		8'bzzzz1000: pos = 3;
		8'bzzz10000: pos = 4;
		8'bzz100000: pos = 5;
		8'bz1000000: pos = 6;
		8'b10000000: pos = 7;
	endcase
end

endmodule

Always nolatches

在使用case语句时避免产生latch的方法。
为避免产生锁存器,必须在所有可能条件下为所有输出分配一个值。仅仅有一个默认的案例是不够的。必须为所有四种情况下的所有四个输出分配一个值,并在所有默认情况下分配一个值。这可能涉及大量不必要的键入。
解决此问题的一种方法是在case语句之前为输出分配一个“默认值”:
always @(*) begin
    up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0;
    case (scancode)
        ... // Set to 1 as necessary.
    endcase
end
这种代码样式可确保在所有可能的情况下为输出分配一个值,除非case语句覆盖赋值。
提醒:逻辑合成器生成一个组合电路,其行为与代码描述的行为等效。硬件不会按顺序“执行”代码行。

module top_module (
    input [15:0]  scancode,
    output reg    left,
    output reg    down,
    output reg    right,
    output reg    up  
); 

always @(*) begin
	up    = 1'b0;
	down  = 1'b0;
	left  = 1'b0;
	right = 1'b0;
	case(scancode)
        16'he075: up    = 1'b1;
        16'he072: down  = 1'b1;
        16'he06b: left  = 1'b1;
        16'he074: right = 1'b1;
        default: begin
        		  up    = 1'b0;
				  down  = 1'b0;
				  left  = 1'b0;
				  right = 1'b0;
        end	
	endcase
end

endmodule

More Verilog Features

Conditional

给定四个无符号数字,找到最小值。无符号数字可以与标准比较运算符(a < b)进行比较。使用条件运算符制作双向最小电路,然后组合其中的几个以创建 4 路最小电路。可能需要一些导线向量作为中间结果。

module top_module (
    input  [7:0]  a, b, c, d,
    output [7:0]  min
);
wire  [7:0]  smaller0;
wire  [7:0]  smaller1;
wire  [7:0]  smaller2;

assign smaller0 = (a > b)? b : a;
assign smaller1 = (c > d)? d : c;
assign smaller2 = (smaller0 > smaller1)? smaller1 : smaller0;
assign min = smaller2;

endmodule

注:也可以设计为流水线的形式,流水线的设计方法可以使系统的运行速率提高。

Reduction

奇偶校验通常用作通过不完美通道传输数据时检测错误的简单方法。创建一个电路,该电路将计算 8 位字节的奇偶校验位(这将向该字节添加第 9 位)。将使用“偶数”奇偶校验,奇偶校验位只是所有8个数据位的XOR。

一个简单的连续位做异或运算。

module top_module (
    input [7:0]  in,
    output       parity
); 

assign parity = ^in;

endmodule

Gates100

在[99:0]中构建具有100个输入的组合电路。
有 3 个输出:

  • out_and:输出100输入与门 &。
  • out_or:100 输入 OR 门 | 的输出。
  • out_xor:100 输入异或门 ^ 的输出。
module top_module( 
    input  [99:0]  in,
    output         out_and,
    output         out_or,
    output         out_xor 
);

assign out_and = & in;
assign out_or = | in;
assign out_xor = ^ in;

endmodule

Vector100r

给定一个 100 位输入向量 [99:0],反转其位排序。

module top_module( 
    input  [99:0]  in,
    output [99:0]  out
);
	integer i;
	always @(*) begin
		for (i=0;i<100;i=i+1) begin
			out[i] = in[99-i];
		end		
	end
endmodule

Popcount255

对输入位宽为255的数计算其各个位为 1 的个数并输出

module top_module( 
    input  [254:0]  in,
    output [7:0]    out 
);

reg [7:0] cnt;
integer i;
always @(*) begin
	cnt = 'd0;
	for (i=0;i<255;i=i+1) begin
		cnt = (in[i])? (cnt+1'b1):cnt;
	end
end
assign out = cnt;

endmodule

Adder100i

通过实例化 100 个全加器来创建一个 100 位二进制行波进位加法器。加法器将两个 100 位数字和一个随身数字相加,以产生 100 位总和并执行。实际实例化全加器,还要从行波进位加法器中的每个全加器输出执行。cout[99]是最后一个全加器的最终执行。

注意对第一个全加器计算时的特殊情况。

module top_module( 
    input  [99:0]  a, b,
    input          cin,
    output [99:0]  cout,
    output [99:0]  sum 
);
	genvar i;
    generate
        for(i=0;i<100;i=i+1) begin:adder
            if(i==0)
                assign{cout[0],sum[0]}=a[0]+b[0]+cin;
            else
                assign{cout[i],sum[i]}=a[i]+b[i]+cout[i-1];
        end           
    endgenerate
    
endmodule

Bcdadd100

以一个四位的全加器模块,计算两个输入数据的相加,其位宽为400。

在这里吐槽一下 HDLBits 自带的编译器有点神经质,有些没必要的细节过度把控,而有些带有技巧性的语法又不支持...

module top_module( 
    input  [399:0]  a,b,
    input           cin,
    output          cout,
    output [399:0]  sum 
);

wire [99:0]  cin_cnt;
genvar i;
generate
	for (i=0;i<100;i=i+1) begin:test
		if (i == 0) begin
			bcd_fadd bcd_fadd_inst(a[3:0],b[3:0],cin,cin_cnt[0],sum[3:0]);
		end
		else begin
			bcd_fadd bcd_fadd_inst(a[4*(i+1)-1:4*i],b[4*(i+1)-1:4*i],cin_cnt[i-1],cin_cnt[i],sum[4*(i+1)-1:4*i]);
		end
		
	end
	assign cout = cin_cnt[99];
endgenerate

endmodule
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

【HDLBits 刷题 4】Verilog Language(4)Procedures 和 More Verilog Features 部分 的相关文章

  • 链表【1】

    文章目录 2 两数相加 1 题目 2 算法原理 3 代码实现 445 两数相加 II
  • 分治-归并算法——LCR 170. 交易逆序对的总数

    文章目录 0 归并排序 1 题目 2 算法原理 3 代码实现 0 归并排序 归并排序是典型的分治 将数组分成若干个子数组 数组两两比较 不是很清楚的 可以查看此篇文章 数据结构 七大排序 这里以力扣 9
  • 如何使用触发器输出作为复位信号的输入

    我在柜台里放了 3D 触发器 一旦达到 5 101 我想将 FF 复位输入设置为高 使用或门 复位为低电平有效 这几乎可以工作 但是 当我最初运行程序时 触发器的 Q 输出都是未知的 因此 最初 或门的复位输入为低电平 但是 因为一开始 Q
  • 如何使用 Verilog 宏模拟 $display?

    我想创建一个具有多个参数的宏 就像 display 一样 我的代码看起来像这样 但它不起作用 define format macro A write s sformatf A 这就是我调用 format macro 的方式 format m
  • Verilog、FPGA、统一寄存器的使用

    我有一个问题 关于我正在开发的 AGC SPI 控制器在我看来奇怪的行为 它是用 Verilog 完成的 针对的是 Xilinx Spartan 3e FPGA 该控制器是一个依赖外部输入来启动的 FSM FSM的状态存储在状态寄存器它没有
  • Verilog HDL ?操作员

    什么是 用 Verilog 做什么 例如 以下命令是什么意思 input first din input 7 0 din output 127 0 parity reg 127 0 parity wire 7 0 feedback assi
  • 「Verilog学习笔记」 Johnson Counter

    专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点 刷题网站用的是牛客网 timescale 1ns 1ns module JC counter input clk input rst n output reg 3 0
  • 串口通信知识点总结

    串口是串行接口 serial port 的简称 也称为串行通信接口或COM接口 串口通信是指采用串行通信协议 serial communication 在一条信号线上将数据一个比特一个比特地逐位进行传输的通信模式 串口按电气标准及协议来划分
  • 无线网络管理系统与无线路由器的区别

    第5章 波形发生器软件设计 本章我们将介绍系统的软件设计 系统中控制软件占有很重要的地位 它不仅要产生波形数据 控制波形的发生 还要控制显示电路和键盘电路 因此系统软件的好坏直接决定着系统的功能和稳定 5 1软件的总体结构 在本系统中 由于
  • [Verilog] Verilog 基本格式和语法

    主页 元存储博客 全文 3000 字 文章目录 1 声明格式 1 1 模块声明 1 2 输入输出声明 1 3 内部信号声明 1 4 内部逻辑声明
  • 「Verilog学习笔记」游戏机计费程序

    专栏前言 本专栏的内容主要是记录本人学习Verilog过程中的一些知识点 刷题网站用的是牛客网 timescale 1ns 1ns module game count input rst n 异位复位信号 低电平有效 input clk 时
  • x 和 z 值在 Verilog 中到底代表什么?

    Verilog 标准定义了四种类型的位值 0 1 x 和 z 其中 0 表示低 1 表示高 x 表示未知 z 表示未驱动网络 有几个问题 x 是否意味着我们不知道该值是 0 还是 1 0 或 1 或 z 或者该值是未知的并且可以是 0 1
  • 用于 Verilog 或 SystemVerilog 的 TAP(测试任何协议)模块

    是否有 TAP 测试任何协议 http testanything org Verilog 的实现 那就太好了 因为这样我就可以使用证明来自动检查我的结果 更新 10 9 09 有人问为什么不使用断言 部分 TAP 为我提供了一些很好的报告
  • Verilog 错误:必须连接到结构网络表达式

    我收到错误 output or inout port Qout must be connected to a structural net expression 我评论了下面代码中发生错误的行 代码被修剪 压缩 我搜索了答案 似乎我无法将输
  • 如何使用 Verilog 和 FPGA 计算一系列组合电路的传播延迟?

    我是 FPGA 和 HDL 的新手 但我正在尝试学习 但无法弄清楚这一点 如何通过多个级别的组合逻辑来计算或估计传播延迟 我可以仅凭经验确定这一点 还是可以在设计时弄清楚 在这种情况下 我使用 FPGA 来实现奇偶校验设置和检查电路 该电路
  • Verilog 中的“net”代表什么?

    我刚刚开始学习Verilog 据我了解 Verilog有net数据类型 什么是net代表 网络就是这样一种数据类型 您不使用它来存储值 它们代表物理连接 您可以将线路视为一种网络数据类型 你可以去网上看看更多here http www ee
  • Verilog 中的 If 语句和分配连线

    我试图弄清楚基于组合逻辑分配电线的基础知识 I have wire val wire x wire a wire b always begin if val 00 I want to assign x a if val 01 I want
  • VIM 高亮匹配开始/结束

    我正在尝试找到一个插件 它将突出显示与 Verilog 匹配的开始 结束语句 VIM 可以使用花括号 方括号 但不能使用它的开始 结束 我希望 VIM 突出显示正确的开始到正确的结束 在我看来 最好的选择是使用 matchit 该脚本是 v
  • 系统 verilog 中没有类型的输入

    我在一个系统 verilog 代码的输入和输出的示例中遇到过module没有说明它们的类型 例如logic wire module mat to stream input 2 0 2 0 2 0 a b input newdata inpu
  • 学习 Verilog 的资源 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我是 Verilog 新手 有人可以推荐学习资源 书籍 视频 博客或任何他们有良好个人经验并帮助他们更

随机推荐

  • HttpClient release connection 该放手的时候必须放手

    Apache commons 系列的HttpClient 相信大家都用过 选择它而非JDK 的java net HttpURLConnection 是为了使用HttpClient 封装的几个实用的功能 目前使用最多的版本还是httpclie
  • 腾讯云2022年双11云服务器配置及报价表汇总

    活动直达 点此进入腾讯云2022年双11活动主会场 腾讯云2022年双11活动的既有轻量应用服务器又有云服务器 购买资格分为个人企业同享和企业用户专享 因此 价格表可分为个人企业同享轻量应用服务器 个人企业同享云服务器 企业专享轻量应用服务
  • 618来袭!我用Python脚本实现了淘宝定时自动秒杀,小白也能轻松搞定!

    准备工作 我们需要把秒杀的商品加入购物车 因为脚本点击的是全选 所以不需要的商品要移出购物车 展示篇幅有限 淘宝秒杀程序的完整源代码已经打包好了 需要的朋友可以扫码加v 我分享给你 过程分析 1 打开某宝网站 pq webdriver Ch
  • 基于Fisco的测压工具使用笔记

    基本过程就是这样了 因为当初写的时候是用OneNote写的 复制过来是图片形式 然后主要的坑就是官方的源码有错误 官方也给了修改意见 根据 修改意见 修改源码 修改完我还碰到一个坑 不知道为什么这个位置缺少文件 移动到这个文件下添加solc
  • 【LeetCode】Day211-不用加减乘除做加法

    题目 剑指 Offer 65 不用加减乘除做加法 中等 题解 不能用加减乘除的题 要考虑位运算 设两数字的二进制形式a b s a b a i 代表a的二进制的第i位 则分为以下四种情况 a i b i 无进位和n i 进位c i 1 0
  • 字符串的总结(atoi和itoa函数的实现)

    目录 一 常见的字符串函数 strlen strcpy strcat strcmp 二 关于atoi函数的实现 三 关于itoa函数的实现 一 常见字符串的函数 strlen strcpy strcat strcmp 1 strlen 求字
  • 在网址上输入www.xxx.com到返回界面给用户发生了什么?

    在网址上输入www xxx com到返回界面给用户发生了什么 DNS域名解析 https blog csdn net m0 37812513 article details 78775629 gt tcp三次握手建立连接 https blo
  • Shiro 如何使用注解式进行授权操作呢?

    转自 Shiro 如何使用注解式进行授权操作呢 下文笔者讲述Shiro进行注解式授权操作的方法分享 如下所示 Shiro注解授权 常使用以下注解字段 如 RequiresRoles RequiresPermissions RequiresA
  • 关闭TCP中135、139、445、593、1025 等端口的操作方法 (转)(记录下)

    操作要领 封闭端口 杜绝网络病毒对这些端口的访问权 以保障计算机安全 减少病毒对上网速度的影响 近日发现有些人感染了新的网络蠕虫病毒 该病毒使用冲击波病毒专杀工具无法杀除 请各位尽快升级计算机上的杀毒软件病毒库 在断开计算机网络连接的情况下
  • AndeSight头文件缺失错误

    使用AndeSight开发山景Demo遇到的问题 路径别带中文名字 一个都不要 其实主要就是一个 当我导入demo之后 编译时遇到问题 缺失 h文件 各种缺失 那么这里我们也可以一个个导入 但是很难受 这里实际上只要在baseSDK建立工程
  • 西门子PLC入门-PLC介绍

    PLC全名 可编程逻辑控制器 Programmable Logic Controller 一种具有微处理器的用于自动化控制的数字运算控制器 可以将控制指令随时载入内存进行储存与执行 PLC由CPU 指令及数据内存 输入 输出接口 电源 数字
  • Stream流处理快速上手最佳实践

    一 引言 JAVA1 8得益于Lambda所带来的函数式编程 引入了一个全新的Stream流概念Stream流式思想类似于工厂车间的 生产流水线 Stream流不是一种数据结构 不保存数据 而是对数据进行加工处理 Stream可以看作是流水
  • 【前端面试题】/【Vue】组件中的data为什么要定义成一个函数而不是一个对象?

    Q 组件中的data为什么要定义成一个函数而不是一个对象 A 因为当定义为一个数组 对象时候 我们改变data中其中一个数据的值的时候 会影响到其他的数据 导致数据污染 而定义为一个函数 则可以避免这个情况 参考 每个组件都是 Vue 的实
  • Cadence(OrCAD)原理图导入到PADS Layout遇到的问题和解决方法

    看到有网友留言说将Cadence画的原理图导入到PADS Layout中没有成功 先在Cadence中导出原理图的网表 当然这里的网表是PADS Layout支持的 asc格式 然后在PADS Layout导入该网表文件 最终出现提示错误的
  • ARM汇编指令

    ARM汇编指令 1 汇编语法 1 1 mov movw r0 63500 0xf80c 将63500放到r0寄存器的低八位中 movt r0 25667 0x6443f80c 将25667放到r0寄存器的高八位中 1 2 lsl 左移 st
  • (十)服务器K8S集群部署SpringBoot项目实战

    1 准备springboot项目 可以在 https start spring io 网站准备一个项目 这里作为k8s的学习所以springboot项目中准备一个简单的访问接口即可 2 服务器环境准备 安装Jdk 1 更新系统软件包 sud
  • MybatisPlus分页类型转换 不要在用循环转换了

    使用MybatisPlus查询的sql 返回的必须是一个对应表实体的泛型分页数据 我们给前端返回只需返回VO 我们可能会循环进行对象复制从新赋值 优化 MybatisPlus分页对象有直接转换的方法 优化前 最终分页对象 Page
  • openwrt中添加自定义驱动模块和APP

    驱动模块添加 1 make menuconfig中的 kernel modules 其中的各个配置选项来自于下面目录中的 mk文件 这里以other mk为对照 后续我们添加的驱动模块 添加到other分支当中 2 建立模块目录 路径是pa
  • 力扣 [104、111、222]

    文章目录 104 二叉树的最大深度 原题链接 思路 代码 111 二叉树的最小深度 原题链接 思路 代码 222 完全二叉树的节点个数 原题链接 思路 广度优先遍历 思路 深度优先遍历 代码 代码 104 二叉树的最大深度 原题链接 思路
  • 【HDLBits 刷题 4】Verilog Language(4)Procedures 和 More Verilog Features 部分

    目录 写在前面 Procedures Alwaysblock1 Alwaysblock2 Always if Always if2 Always case Always case2 Always casez Always nolatches