【HDLBits 刷题 8】Circuits(4)Sequential Logic---Shifts Registers More Circuits

2023-10-07 22:30

本文主要是介绍【HDLBits 刷题 8】Circuits(4)Sequential Logic---Shifts Registers More Circuits,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

写在前面

Shifts Registers

Shift4

Rotate100

Shift18 

Lfsr5

Mt2015 lfsr

Lfsr32

Shift registier

Shift registier2

3 input LUT

More Circuits

Rule90

Rule110

Conwaylife


写在前面

本篇博客对 Circuits 部分的组合逻辑前两节做答案和部分解析,一些比较简单的题目就直接给出答案,有些难度再稍作讲解,每道题的答案不一定唯一,可以有多种解决方案,欢迎共同讨论。


Shifts Registers

Shift4

构建一个 4 位移位寄存器(右移位),具有异步复位、同步负载和使能功能。

  • areset:将移位寄存器重置为零。
  • load:加载带有数据的移位寄存器[3:0]而不是移位。
  • ena:向右移位(q[3] 变为零,q[0] 移出并消失)。
  • q:移位寄存器的内容。

如果 load 和 ena 输入都置位,则 load 输入具有更高的优先级。 

module top_module(input             clk,input             areset,  // async active-high reset to zeroinput             load,input             ena,input      [3:0]  data,output reg [3:0]  q
); always @(posedge clk or posedge areset) beginif (areset) beginq <= 'd0;endelse if (load) beginq <= data;endelse if (ena) beginq <= {1'b0,q[3:1]};endelse beginq <= q;end
endendmodule

Rotate100

构建一个 100 位左/右旋转器,具有同步负载和左/右使能。旋转器从寄存器的另一端移入移出位,这与丢弃移出位并移位为零的移位不同。如果启用旋转器将旋转位,并不会修改/丢弃。

  • load:加载带有数据的移位寄存器[99:0]而不是旋转。
  • ena[1:0]:选择是否旋转以及旋转方向。
  • 2'b01 向右旋转一位
  • 2'b10 向左旋转一位
  • 2'b00 和 2'b11 不旋转。
  • q:旋转器的内容物。
module top_module(input             clk,input             load,input      [1:0]  ena,input      [99:0] data,output reg [99:0] q
); 
always @(posedge clk) beginif (load) beginq <= data;endelse begincase(ena)2'b01: q <= {q[0],q[99:1]};2'b10: q <= {q[98:0],q[99]};default: q <= q;endcaseend
endendmodule

Shift18 

构建一个具有同步负载的 64 位算术移位寄存器。移位器可以向左和向右移动,也可以按数量选择1位或8位位置。算术右移位在移位寄存器中数字的符号位(在本例中为q[63])移位,而不是像逻辑右移那样为零。考虑算术右移的另一种方法是,它假设被移位的数字是有符号的并保留符号,因此算术右移将有符号除以有符号数的2次幂。
逻辑左移和算术左移之间没有区别。

  • .load:加载带有数据的移位寄存器[63:0]而不是移位。
  • .ena:选择是否移动。
  • .amount:选取要移动的方向和量。
  •    2'b00:向左移动 1 位。
  •    2'b01:向左移动 8 位。
  •    2'b10:向右移动 1 位。
  •    2'b11:向右移动 8 位。
  • .q:变速器的内容。
module top_module(input              clk,input              load,input              ena,input      [1:0]   amount,input      [63:0]  data,output reg [63:0]  q
); always @(posedge clk) beginif (load) beginq <= data;endelse if (ena) begincase(amount)2'b00 : q <= {q[62:0],1'b0};2'b01 : q <= {q[55:0],8'b0};2'b10 : q <= {q[63],q[63:1]};2'b11 : q <= {{8{q[63]}},q[63:8]};endcaseend
endendmodule

Lfsr5

线性反馈移位寄存器是一种移位寄存器,通常具有几个XOR门,以产生移位寄存器的下一个状态。伽罗瓦LFSR是一种特殊的排列方式,其中带有“抽头”的位位置与输出位进行XOR运算以产生其下一个值而位位置没有分路器移位。如果仔细选择丝锥位置,则可以使LFSR达到“最大长度”。n 位的最大长度 LFSR 循环通过 2n重复前为 -1 个状态(永远不会达到全零状态)。
下图显示了一个 5 位最大长度伽罗瓦 LFSR,在位位置 5 和 3 处具有抽头。(点击位置通常从 1 开始编号)。请注意,为了保持一致性,我在位置 5 绘制了 XOR 门,但其中一个 XOR 门输入为 0。 

module top_module(input         clk,input         reset,    // Active-high synchronous reset to 5'h1output [4:0]  q
); always @(posedge clk) beginif (reset) beginq <= 5'h1;endelse beginq[4] <= q[0];q[3] <= q[4];q[2] <= q[3] ^ q[0];q[1] <= q[2];q[0] <= q[1];end
endendmodule

Mt2015 lfsr

为此时序电路编写 Verilog 代码(子模块是可以的,但顶层必须命名为 top_module)。假设您要在DE1-SoC板上实现电路。将 R 输入连接到软件开关,将时钟连接到 KEY[0],将 L 连接到 KEY[1]。将 Q 输出连接到红灯 LEDR。

module top_module (input  [2:0]  SW,      // Rinput  [1:0]  KEY,     // L and clkoutput [2:0]  LEDR     // Q
); 
wire [2:0]   R;
wire         L;
wire         clk;
reg  [2:0]   Q;assign R = SW;
assign clk = KEY[0];
assign L = KEY[1];always @(posedge clk) beginif (L) beginQ[0] <= R[0];endelse beginQ[0] <= Q[2];endend always @(posedge clk) beginif (L) beginQ[1] <= R[1];endelse beginQ[1] <= Q[0];endendalways @(posedge clk) beginif (L) beginQ[2] <= R[2];endelse beginQ[2] <= Q[1] ^ Q[2];endendassign LEDR = Q;
endmodule

Lfsr32

构建一个 32 位 LFSR,在位位置 32、22、2 和 1 处使用抽头。 

module top_module(input          clk,input          reset,    // Active-high synchronous reset to 32'h1output [31:0]  q
); always @(posedge clk) beginif (reset) beginq <= 32'h1;endelse beginq[31] <= q[0];q[30] <= q[31];q[29] <= q[30];q[28] <= q[29];q[27] <= q[28];q[26] <= q[27];q[25] <= q[26];q[24] <= q[25];q[23] <= q[24];q[22] <= q[23];q[21] <= q[22] ^ q[0];q[20] <= q[21];q[19] <= q[20];q[18] <= q[19];q[17] <= q[18];q[16] <= q[17];q[15] <= q[16];q[14] <= q[15];q[13] <= q[14];q[12] <= q[13];q[11] <= q[12];q[10] <= q[11];q[9]  <= q[10];q[8]  <= q[9];q[7]  <= q[8];q[6]  <= q[7];q[5]  <= q[6];q[4]  <= q[5];q[3]  <= q[4];q[2]  <= q[3];q[1]  <= q[2] ^ q[0];q[0]  <= q[1] ^ q[0];end
endendmodule

Shift registier

实现移位寄存器

module top_module (input     clk,input     resetn,   // synchronous resetinput     in,output    out
);
reg   out1,out2,out3;always @(posedge clk) beginif (!resetn) beginout1 <= 'd0;out2 <= 'd0;out3 <= 'd0;out  <= 'd0;endelse beginout1 <= in;out2 <= out1;out3 <= out2;out  <= out3;end
endendmodule

Shift registier2

为移位寄存器编写一个顶层 Verilog 模块(top_module)假设 n = 4。在顶层模块中实例化 MUXDFF 子模块。

  • R   to SW
  • clk to KEY[0]
  • E   to KEY[1]
  • L   to KEY[2]
  • w   to KEY[3]
  • Q   to LEDR[3:0]

module top_module (input  [3:0]   SW,input  [3:0]   KEY,output [3:0]   LEDR
); MUXDFF MUXDFF_inst(.R(SW),.clk(KEY[0]),.E(KEY[1]),.L(KEY[2]),.w(KEY[3]),.Q(LEDR)  	);endmodulemodule MUXDFF (input  [3:0]       R,input              clk,input              E,input              L,input              w,output reg [3:0]   Q  
);always @(posedge clk) beginif (E) beginif (L) beginQ[3] <= R[3];endelse beginQ[3] <= w;endendelse if (!E) beginif (L) beginQ[3] <= R[3];endelse beginQ[3] <= Q[3];endend
endalways @(posedge clk) beginif (E) beginif (L) beginQ[2] <= R[2];endelse beginQ[2] <= Q[3];endendelse if (!E) beginif (L) beginQ[2] <= R[2];endelse beginQ[2] <= Q[2];endend
endalways @(posedge clk) beginif (E) beginif (L) beginQ[1] <= R[1];endelse beginQ[1] <= Q[2];endendelse if (!E) beginif (L) beginQ[1] <= R[1];endelse beginQ[1] <= Q[1];endend
endalways @(posedge clk) beginif (E) beginif (L) beginQ[0] <= R[0];endelse beginQ[0] <= Q[1];endendelse if (!E) beginif (L) beginQ[0] <= R[0];endelse beginQ[0] <= Q[0];endend
endendmodule

3 input LUT

在这个问题中,将为8x1存储器设计一个电路,其中写入存储器是通过移位来完成的,并且读取是“随机访问”,就像在典型的RAM中一样。然后,将使用该电路实现3输入逻辑功能。首先,创建一个具有8个D型触发器的8位移位寄存器。将触发器输出标记为 Q[0]...问题[7]移位寄存器输入应称为S,它为Q[0]的输入供电(MSB首先移位)。启用输入控制是否移动。然后,扩展电路以具有3个额外的输入A,B,C和一个输出Z。电路的行为应如下所示:当ABC为000时,Z=Q[0],当ABC为
001时,Z=Q[1],依此类推。电路应仅包含8位移位寄存器和多路复用器。(题外话:该电路称为3输入查找表(LUT))。

module top_module (input    clk,input    enable,input    S,input    A, B, C,output   Z 
);reg [7:0]  FF;always @(posedge clk) beginif (enable) beginFF <= {FF[6:0],S};endelse beginFF <= FF;endend assign Z = FF[{A,B,C}];endmodule

More Circuits

Rule90

有一个一维的单元格数组(打开或关闭)。在每个时间步长中,每个单元格的状态都会发生变化。在规则110中,每个单元格的下一个状态仅取决于其自身及其两个相邻的数据:

module top_module(input           clk,input           load,input  [511:0]  data,output [511:0]  q
); 
always @(posedge clk) beginif (load) beginq <= data;endelse beginq <= (~{1'b0,q[511:1]} & q) | (q & ~{q[510:0],1'b0}) | {~{1'b0,q[511:1]} & {q[510:0],1'b0}} | {~q & {q[510:0],1'b0}};end
endendmodule

Rule110

Conway的Game of Life是一个二维元胞自动机。
“游戏”在二维细胞网格上进行,其中每个细胞要么是1(活的)要么是0(死的)。在每个时间步长中,每个单元都会根据它有多少个邻数而改变状态:

  • 0-1 邻数:单元格变为 0。
  • 2 个邻数:单元格状态不会更改。
  • 3 个邻数:单元格变为 1。
  • 4 个以上的邻数:单元格变为 0。

在本电路中,将使用16x16网格。为了使事情更有趣,我们将使用16x16环形线圈,其中两侧环绕到网格的另一侧。例如,角单元格 (0,0) 有 8 个相邻项:(15,1)、
(15,0)、(15,15)、(0,1)、(0,15)、(1,1)、(1,0) 和 (1,15)
16x16 网格由长度为 256 的向量表示,其中每行 16 个单元格由一个子向量表示:q[15:0] 为行 0,q[31:16] 为第 1 行,依此类推。

load:在下一个时钟边沿将数据加载到q中,用于加载初始状态。
q:游戏的 16x16 当前状态,每时钟周期更新一次。

游戏状态应在每个时钟周期前进一个时间步长。有点类似扫雷游戏,判定周围的炸弹,这道题就是判断相应的位周围有多少个1,把位的周围的数全部加起来就是1的个数。

module top_module(input           clk,input           load,input  [255:0]  data,output [255:0]  q 
);reg [3:0] count;integer i;always @(posedge clk)beginif (load) beginq <= data;endelse beginfor(i=0;i<256;i++)beginif (i == 0) begincount = q[255] + q[240] + q[241] + q[15] + q[1] + q[31] + q[16] + q[17];endelse if (i == 15)begincount = q[254] + q[255] + q[240] + q[14] + q[0] + q[30] + q[31] + q[16];endelse if (i == 240) begincount = q[239] + q[224] + q[225] + q[255] + q[241] + q[15] + q[0] + q[1];endelse if (i == 255) begincount = q[238] + q[239] + q[224] + q[254] + q[240] + q[15] + q[0] + q[14];endelse if (i>0 && i<15) begincount = q[239+i]+q[240+i]+q[241+i]+q[i-1]+q[i+1]+q[i+15]+q[i+16]+q[i+17];endelse if (i>240 && i<255) begincount = q[i-17]+q[i-16]+q[i-15]+q[i-1]+q[i+1]+q[i-239]+q[i-240]+q[i-241];endelse if (i%16 == 0) begincount = q[i-1]+q[i-16]+q[i-15]+q[i+15]+q[i+1]+q[i+31]+q[i+16]+q[i+17];endelse if (i%16 == 15) begincount = q[i-17]+q[i-16]+q[i-31]+q[i-1]+q[i-15]+q[i+15]+q[i+16]+q[i+1];endelse begincount = q[i-17]+q[i-16]+q[i-15]+q[i-1]+q[i+1]+q[i+15]+q[i+16]+q[i+17];endcase(count)4'd2:q[i] <= q[i];4'd3:q[i] <= 1'b1;default:q[i] <= 1'b0;endcaseendendendendmodule

Conwaylife

有一个一维的单元格数组(打开或关闭)。在每个时间步长中,每个单元的下一个状态是该单元的两个当前邻居的 XOR。表示此规则的更详细方式如下表所示,其中单元格的下一个状态是自身及其两个相邻的函数。

module top_module(input           clk,input           load,input  [511:0]  data,output [511:0]  q 
);integer i;
always @(posedge clk) beginif (load) beginq <= data;endelse beginq <= {1'b0,q[511:1]} ^ {q[510:0],1'b0};end
endendmodule

这篇关于【HDLBits 刷题 8】Circuits(4)Sequential Logic---Shifts Registers More Circuits的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/160859

相关文章

【每日刷题】Day113

【每日刷题】Day113 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 91. 解码方法 - 力扣(LeetCode) 2. LCR 098. 不同路径 - 力扣(LeetCode) 3. 63. 不同路径 II - 力扣(LeetCode) 1. 91. 解码方法 - 力扣(LeetCode) //思路:动态规划。 cl

hot100刷题第1-9题,三个专题哈希,双指针,滑动窗口

求满足条件的子数组,一般是前缀和、滑动窗口,经常结合哈希表; 区间操作元素,一般是前缀和、差分数组 数组有序,更大概率会用到二分搜索 目前已经掌握一些基本套路,重零刷起leetcode hot 100, 套路题按套路来,非套路题适当参考gpt解法。 一、梦开始的地方, 两数之和 class Solution:#注意要返回的是数组下标def twoSum(self, nums: Lis

代码随想录刷题day25丨491.递增子序列 ,46.全排列 ,47.全排列 II

代码随想录刷题day25丨491.递增子序列 ,46.全排列 ,47.全排列 II 1.题目 1.1递增子序列 题目链接:491. 非递减子序列 - 力扣(LeetCode) 视频讲解:回溯算法精讲,树层去重与树枝去重 | LeetCode:491.递增子序列_哔哩哔哩_bilibili 文档讲解:https://programmercarl.com/0491.%E9%80%92%E

代码随想录刷题day24丨93.复原IP地址 ,78.子集 , 90.子集II

代码随想录刷题day24丨93.复原IP地址 ,78.子集 , 90.子集II 1.题目 1.1复原IP地址 题目链接:93. 复原 IP 地址 - 力扣(LeetCode) 视频讲解:回溯算法如何分割字符串并判断是合法IP?| LeetCode:93.复原IP地址_哔哩哔哩_bilibili 文档讲解:https://programmercarl.com/0093.%E5%A4%8

【笔记】数据结构刷题09

快速排序 215. 数组中的第K个最大元素 class Solution {public:int findKthLargest(vector<int>& nums, int k) {return divide(nums,0,nums.size()-1,nums.size()-k);}int divide(vector<int>& nums,int left,int right,int k)

C语言:刷题日志(1)

一.阶乘计算升级版 本题要求实现一个打印非负整数阶乘的函数。 其中n是用户传入的参数,其值不超过1000。如果n是非负整数,则该函数必须在一行中打印出n!的值,否则打印“Invalid input”。 首先,知道阶乘是所有小于及等于该数的正整数的积,并且0的阶乘为1。那么我们先来个简单的阶乘计算吧。 #include<stdio.h>int Fact(int n){if (n <=

【每日刷题】Day112

【每日刷题】Day112 🥕个人主页:开敲🍉 🔥所属专栏:每日刷题🍍 🌼文章目录🌼 1. 1137. 第 N 个泰波那契数 - 力扣(LeetCode) 2. 面试题 08.01. 三步问题 - 力扣(LeetCode) 3. LCR 088. 使用最小花费爬楼梯 - 力扣(LeetCode) 1. 1137. 第 N 个泰波那契数 - 力扣(LeetCo

【数据结构】【java】leetcode刷题记录--链表

简介 链表是一种常见的基础数据结构,它由一系列节点组成,每个节点包含数据域和指向下一个节点的指针。在Java中,链表通常用于实现动态数据结构,因为它可以根据需要动态地增加或减少节点。 链表简介: 节点结构:链表中的每个元素称为节点(Node),每个节点包含两部分:数据域(存储数据)和指针域(存储下一个节点的地址)动态性:链表的长度不是固定的,可以根据需要动态地增减节点。内存分配:链表中的节点

代码随想录 刷题记录-28 图论 (5)最短路径

一、dijkstra(朴素版)精讲 47. 参加科学大会 思路 本题就是求最短路,最短路是图论中的经典问题即:给出一个有向图,一个起点,一个终点,问起点到终点的最短路径。 接下来讲解最短路算法中的 dijkstra 算法。 dijkstra算法:在有权图(权值非负数)中求从起点到其他节点的最短路径算法。 需要注意两点: dijkstra 算法可以同时求 起点到所有节点的最短路径权值不

【Hot100算法刷题集】哈希-01-两数之和(暴力枚举再优化,也不是哈希表的对手)

🏠关于专栏:专栏用于记录LeetCode中Hot100专题的所有题目 🎯每日努力一点点,技术变化看得见 题目转载 题目描述 🔒link->题目跳转链接 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出和为目标值 target 的那 两个整数,并返回它们的数组下标。 你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。 你可以按任