4.3 HDLBits —— 时序逻辑电路之移位寄存器

4 位移位寄存器

设计一个4 位右移移位寄存器,具备异步复位、同步置数、移位使能功能。

端口功能说明

areset(异步复位):将移位寄存器全部清零;

load(同步置数):给移位寄存器并行载入 4 位输入数据data3:0,替代移位操作;

ena(移位使能):执行右移操作(移位规则:最高位q3补 0,最低位q0移出寄存器并丢弃);

q:移位寄存器的存储输出值。

优先级规则

若置数信号load与移位使能ena同时为高电平(有效),置数 load 拥有更高执行优先级。

参考答案

java 复制代码
module top_module(
    input clk,
    input areset,  // async active-high reset to zero 高电平有效异步复位,复位后寄存器清零
    input load,    // 同步并行置数信号,优先级高于移位使能ena
    input ena,     // 右移使能信号,有效时执行右移操作
    input [3:0] data, // 4位并行输入数据,load有效时载入寄存器
    output reg [3:0] q // 移位寄存器对外输出端口
); 
    
    // 时序逻辑敏感列表:时钟上升沿、异步复位上升沿,满足异步复位电路规范
    always @(posedge clk or posedge areset) begin
        // 异步复位触发:areset为高电平时,立刻将寄存器置0,不受时钟控制
        if (areset) begin
            q <= 4'd0;
        end 
        // 置数load优先级最高:复位无效且load=1,并行载入输入data
        else if(load) begin
            q <= data;
        end 
        // load无效、ena有效:执行逻辑右移,高位补0,最低位移出丢弃
        else if(ena) begin
            q <= q >> 1;
        end 
        // load、ena均无效:保持原值
        else begin
            q <= q;
        end
    end

endmodule

输出结果

循环左 / 右移寄存器(循环器)

设计一个100 位双向循环移位寄存器(可左旋 / 右旋),带有同步并行置数功能与左 / 右旋使能控制。 循环寄存器和普通移位寄存器存在区别:普通移位寄存器会舍弃移出的比特、空出位补 0;而循环寄存器会把一端移出的比特,从寄存器另一端重新移入,所有比特不会丢失、数值不会被修改,仅循环换位。

端口功能定义

  • load(同步置数信号):高电平有效时,将 100 位并行输入数据data99:0载入寄存器,替代循环移位操作;
  • ena1:0(2 位旋转方向使能控制端):决定是否执行旋转、以及旋转方向:
    • 2'b01:寄存器整体右旋 1 位;
    • 2'b10:寄存器整体左旋 1 位;
    • 2'b00、2'b11:不执行任何旋转,寄存器保持原值;
  • q:循环寄存器内部存储的全部比特输出

参考答案

java 复制代码
//=============================================================
// 模块功能:100位双向循环移位寄存器(带同步并行置数)
// 核心能力:支持同步载入初始数据、循环左移、循环右移、数值保持四种工作模式
// 时钟规则:纯同步时序,仅在时钟上升沿更新寄存器状态,无异步复位信号
// 优先级规则:并行置数load > 移位控制ena > 保持原值
//=============================================================
module top_module(
    input         clk,         // 系统同步时钟,所有状态更新仅在时钟上升沿触发
    input         load,        // 同步并行置数控制信号,高电平有效,优先级高于所有移位操作
    input  [1:0]  ena,         // 移位模式选择控制位,4组编码对应不同工作模式
    input  [99:0] data,        // 100位并行待载入数据,load拉高时整体写入输出寄存器q
    output reg [99:0] q        // 100位移位寄存器输出,reg型用于时序逻辑存储状态
); 
    
//=============================================================
// 时序逻辑块说明
// 敏感列表仅包含posedge clk:标准同步时序写法,无异步复位,电路时序稳定性高
// 分支判断严格按优先级排布,全覆盖ena全部4种取值,不会生成意外锁存器
//=============================================================
always @(posedge clk) begin
    // 模式1:同步并行置数(最高优先级)
    // 只要load为高,无视ena当前取值,直接把外部data完整写入寄存器,覆盖原有移位结果
    if (load) begin
        q <= data; 
    end 

    // 模式2:ena=2'b01 执行1位循环右移
    // 循环右移规则:所有位整体向右移动1格;原本最右侧最低位q[0]移出后,补到最左侧最高位位置
    // 拼接拆解:{移出的最低位q[0], 原高位段q[99:1]}
    // 举例(简化4位类比:q=4'b1001)→ 循环右移1位得到4'b1100
    else if(ena == 2'b01) begin 
        q <= {q[0], q[99:1]}; 
    end 

    // 模式3:ena=2'b10 执行1位循环左移
    // 循环左移规则:所有位整体向左移动1格;原本最左侧最高位q[99]移出后,补到最右侧最低位位置
    // 拼接拆解:{原低位段q[98:0], 移出的最高位q[99]}
    // 举例(简化4位类比:q=4'b1001)→ 循环左移1位得到4'b0011
    else if(ena == 2'b10) begin
        q <= {q[98:0], q[99]};
    end 

    // 模式4:ena=2'b00 / 2'b11 寄存器保持原值
    // 两种编码均不触发移位、不触发置数,寄存器锁存当前数值不变
    else begin
        q <= q;
    end
end

endmodule

输出结果

算术左 / 右移

设计一个64 位算术移位寄存器,具备同步并行置数功能。该移位寄存器可实现左移、右移,移位位数为 1 位或 8 位,由 amount 信号选择。

算术移位核心规则说明

  • 算术右移:移位时空出的高位填充寄存器的符号位(本题符号位为q63),而非逻辑右移的补 0。 算术右移的本质是将寄存器数值视作有符号数,移位后保持正负符号不变,等价于对有符号数做除以 2 的幂次运算。
  • 算术左移与逻辑左移无任何区别:左移时低位统一补 0。
    端口功能定义
  • load(同步置数信号):有效时将 64 位并行输入数据data63:0载入寄存器,替代移位操作;
  • ena(移位使能):控制是否执行移位动作;
  • amount1:0(移位模式选择):决定移位方向与移位位数:
    • 2'b00:左移 1 位
    • 2'b01:左移 8 位
    • 2'b10:算术右移 1 位
    • 2'b11:算术右移 8 位
  • q:移位寄存器内部存储数值输出端口

参考答案

java 复制代码
//=============================================================
// 模块功能:64位可移位宽度可控移位寄存器(同步并行置数+移位模式选择)
// 控制逻辑优先级:并行置数load > 移位使能ena > 数值保持
// 移位规则细分:
// amount=00 逻辑左移1位、amount=01 逻辑左移8位
// amount=10 算术右移1位、amount=11 算术右移8位
// 时序特性:纯同步时序,仅时钟上升沿更新寄存器,无异步复位
//=============================================================
module top_module(
    input         clk,         // 全局同步时钟,所有寄存器状态仅上升沿刷新
    input         load,       // 同步并行置数高有效,优先级最高,直接载入data覆盖旧值
    input         ena,        // 移位总使能,load无效时ena=1才执行case分支移位操作
    input  [1:0]  amount,     // 移位模式/移位位数选择控制位,4种编码对应4类移位
    input  [63:0] data,       // 64位并行预置数据,load拉高时完整写入寄存器q
    output reg [63:0] q       // 64位移位寄存器时序输出,reg型寄存状态
); 

// 同步时序块:敏感列表仅时钟上升沿,标准寄存器建模写法
always @(posedge clk) begin
    // 分支1:最高优先级同步并行置数,屏蔽所有移位逻辑
    if (load) begin
        q <= data;
    end 
    // 分支2:置数关闭、移位总开关打开,按amount选择移位类型与位数
    else if(ena) begin
        case (amount) 
            // 2'b00:逻辑左移1位
            // 逻辑左移特点:低位空位补0,高位移出位直接丢弃
            // 拼接结构:原低63位q[62:0]整体左移,最低位补1位0,总位宽64
            2'b00 : q <= {q[62:0], 1'b0};
            // 2'b01:逻辑左移8位
            // 低位连续补8个0,高位丢弃移出的8bit,剩余低56位左移排布
            2'b01 : q <= {q[55:0], 8'b0};
            // 2'b10:算术右移1位(适配有符号数)
            // 算术右移特点:高位空位填充最高符号位q[63],低位移出位丢弃
            // 拼接结构:复制2份符号位填充高位 + 原高62位q[62:1]右移排布,总位宽64
            2'b10 : q <= {{2{q[63]}}, q[62:1]};
            // 2'b11:算术右移8位
            // 高位连续填充9份符号位q[63],剩余q[62:8]共56位右移排布,总位宽64
            2'b11 : q <= {{9{q[63]}}, q[62:8]};
            // default兜底:规避综合工具报分支不全警告,异常编码保持原值
            default: q <= q;
        endcase
    end 
    // 分支3:置数、移位均关闭,寄存器锁存当前数值,避免生成隐性锁存器
    else begin
        q <= q;
    end
end

endmodule

输出结果

5 位线性反馈移位寄存器

线性反馈移位寄存器(LFSR)本质是一种移位寄存器,内部搭配少量异或门,用于生成寄存器的下一状态。伽罗瓦型线性反馈移位寄存器(Galois LFSR) 是其中一种特定结构:带有抽头(tap)的比特位会与寄存器输出比特做异或运算,得到该位置的下一个数值;无抽头的比特位仅单纯移位。

若抽头位置经过严谨选取,该 LFSR 可构成最长序列 LFSR(maximum-length LFSR)。n 位最长序列 LFSR 在状态重复前,会遍历 2n−12^n-12n−1 种不同状态(全零状态永远不会出现)。

下图为5 位最长序列伽罗瓦 LFSR,抽头设置在第 5 位、第 3 位(抽头位序号常规从 1 开始计数)。为结构统一,图中将异或门画在第 5 位位置,其中一路异或输入恒为 0。

搭建该线性反馈移位寄存器(LFSR)。复位信号需将线性反馈移位寄存器复位至数值1。

参考答案

java 复制代码
//=============================================================
// 模块功能:5位Galois(伽罗瓦)型线性反馈移位寄存器LFSR
// 复位规则:高电平同步复位,初始状态固定 5'h01(二进制00001)
// 反馈抽头规则:反馈取自最低位q_reg[0],仅bit2做异或运算,其余位串行移位传递
// 位编号映射:内部q_reg[4]~q_reg[0] 对应题目bit5~bit1
// 时序类型:纯同步时序,仅时钟上升沿刷新寄存器状态
//=============================================================
module top_module(
    input clk,               // 系统同步时钟,所有寄存器仅在时钟上升沿更新状态
    input reset,             // 高电平有效同步复位,复位后寄存器强制初始值5'h1(00001)
    output [4:0] q           // 5位LFSR寄存器最终对外并行输出端口
); 
    // 内部状态寄存器:保存LFSR每一拍的5位移位状态
    // q_reg[4] → 最高位(题目bit5);q_reg[0] → 最低位(题目bit1)
    reg [4:0] q_reg;

//=============================================================
// 同步时序逻辑块
// 敏感列表仅posedge clk:标准同步复位写法,无异步毛刺风险
// 优先级:同步复位 > 正常移位反馈逻辑
//=============================================================
always @(posedge clk) begin
    // 同步复位分支:复位信号拉高,无视移位逻辑,强制载入初始值
    if (reset) begin
        q_reg <= 5'h1;  // 初始二进制:00001,避免全0静止死锁(LFSR全0无法自迭代)
    end 
    // 复位撤销,执行Galois LFSR移位+反馈迭代
    else begin
        // q_reg[4](bit5):反馈源为最低位q_reg[0],异或常数0不改变数值,等价直接传递q_reg[0]
        q_reg[4] <= q_reg[0] ^ 1'b0;
        // q_reg[3](bit4):普通移位位,无反馈抽头,直接继承上一拍最高位q_reg[4]
        q_reg[3] <= q_reg[4];
        // q_reg[2](bit3):唯一抽头位,本位原值q_reg[3] 异或全局反馈源q_reg[0]生成新值
        q_reg[2] <= q_reg[3] ^ q_reg[0];
        // q_reg[1](bit2):普通移位位,继承上一拍q_reg[2]
        q_reg[1] <= q_reg[2];
        // q_reg[0](bit1):普通移位位,继承上一拍q_reg[1],完成整级右移链式传递
        q_reg[0] <= q_reg[1];
    end
end

// 组合逻辑连续赋值:内部寄存器状态直接输出到顶层端口q
assign q = q_reg;

endmodule

输出结果

3 位线性反馈移位寄存器

摘自2015年期中试卷第5题。另见本题第一部分:mt2015_muxdff

编写该时序电路的Verilog代码(允许使用子模块,但顶层模块必须命名为top_module)。假设你将在DE1-SoC开发板上实现该电路:将R输入端连接至拨码开关SW,时钟信号接入按键KEY0,控制信号L接入按键KEY1,输出信号Q连接至红色LED灯LEDR。

参考答案

java 复制代码
//=============================================================
// 顶层模块:3路带多路选择输入的D触发器阵列
// 功能模式:
// 1. KEY[1]=1(并行载入模式):直接把拨码开关SW[2:0]写入3级触发器,LED同步显示SW数值
// 2. KEY[1]=0(串行移位反馈模式):触发器链式移位,最高位引入q1^q2线性反馈运算
// 硬件对应:SW拨码输入、KEY按键控制模式/时钟、LEDR状态输出
//=============================================================
module top_module (
        input [2:0] SW,      // 3位拨码开关:并行载入原始输入数据R[2:0]
        input [1:0] KEY,     // KEY[1]=模式控制L(1载入/0移位);KEY[0]=全局同步时钟clk
        output [2:0] LEDR    // 3位LED输出:实时展示触发器存储状态Q[2:0]
);
    // 内部连线定义:各级D触发器的数据输入端口
    wire d0,d1,d2;
    // 内部连线定义:各级D触发器的寄存输出端口
    wire q0,q1,q2;
    
    // ========== 最低位触发器d0多路选择逻辑 ==========
    // L=KEY[1]=1:并行载入SW[0];L=0:串行环路接入最高位输出q2,形成循环移位链路
    assign d0 = KEY[1] ? SW[0] : q2 ;

    // ========== 中间位触发器d1多路选择逻辑 ==========
    // L=1:并行载入SW[1];L=0:接收低位触发器q0移位输出,完成逐级右移传递
    assign d1 = KEY[1] ? SW[1] : q0 ;

    // ========== 最高位触发器d2多路选择逻辑(带反馈抽头) ==========
    // L=1:并行载入SW[2];L=0:引入线性反馈q1^q2,实现LFSR类迭代运算
    assign d2 = KEY[1] ? SW[2] : (q1 ^ q2) ;
    
    // 例化3个上升沿触发D触发器,共用KEY[0]时钟节拍同步刷新
    dff_d dff_d0(.clk(KEY[0]),.d(d0),.q(q0)); // 第0级(最低位)触发器
    dff_d dff_d1(.clk(KEY[0]),.d(d1),.q(q1)); // 第1级(中间位)触发器
    dff_d dff_d2(.clk(KEY[0]),.d(d2),.q(q2)); // 第2级(最高位)触发器
    
    // 位拼接输出:高位在前{q2,q1,q0},和SW位序保持一致,LED直观对应开关状态
    assign LEDR = {q2,q1,q0};

endmodule

//=============================================================
// 基础子模块:标准上升沿D触发器
// 时序规则:仅时钟上升沿采样输入d、更新输出q;其余时刻保持原有寄存值
// 无复位/置位,结构极简,适配多级触发器级联场景
//=============================================================
module dff_d(
    input  clk, // 触发器同步时钟,上升沿触发更新
    input  d,   // 待锁存的数据输入
    output reg q// 寄存后的数据输出,reg型存储状态
);
    always @(posedge clk) begin
        // 时钟上升沿:采样当前d值,写入寄存器输出q
        q <= d;
    end
endmodule

输出结果

32 位线性反馈移位寄存器

详见Lfsr5说明。构建一个32位伽罗瓦线性反馈移位寄存器,抽头位置位于第32、22、2、1比特位。

参考答案

java 复制代码
//=============================================================
// 模块功能:32位Galois(伽罗瓦)结构线性反馈移位寄存器LFSR
// 复位规则:高电平同步复位,初始固定值 32'h00000001,规避全0死锁(全0状态无法迭代变化)
// 位编号映射:题目物理位bit1~bit32 ↔ 寄存器索引q_reg[0]~q_reg[31]
// 反馈基准:全局反馈信号统一取自最低位 q_reg[0],在指定抽头位插入异或运算,其余位串行右移传递
// 时序特性:纯同步时序,仅时钟上升沿刷新状态,复位信号同步采样时钟节拍
//=============================================================
module top_module(
    input clk,                  // 全局同步时钟,所有寄存器状态仅在时钟上升沿更新
    input reset,                // 高电平有效同步复位,复位后寄存器强制赋值32'h1
    output [31:0] q             // 32位LFSR内部状态并行对外输出
); 
    // 32位状态寄存器:存储LFSR每一拍迭代结果
    // 索引对应:q_reg[31]=bit32、q_reg[21]=bit22、q_reg[1]=bit2、q_reg[0]=bit1
    reg [31:0] q_reg;

//=============================================================
// 同步时序逻辑块
// 敏感列表仅posedge clk:标准同步复位写法,时序收敛性强、无异步复位毛刺隐患
// 执行优先级:同步复位 > 正常移位+反馈迭代逻辑
//=============================================================
always @(posedge clk) begin
    // 复位触发:拉高时无视移位逻辑,载入初始值,全0状态会永久锁死所以禁用0初值
    if (reset) begin
        q_reg <= 32'h1;
    end 
    // 复位撤销,执行Galois分段移位+抽头异或反馈
    else begin
        // 最高位bit32(q_reg[31]):接收全局反馈q_reg[0],异或0不改变数值,为格式冗余写法可简化
        q_reg[31] <= q_reg[0] ^ 1'b0;

        // bit31~bit23(q_reg[30:22]):无抽头连续区间,整体右移,直接拷贝左侧高位上一拍数值
        q_reg[30:22] <= q_reg[31:23];

        // bit22(q_reg[21]):首个抽头位,本位常规移位输入 q_reg[22] 与全局反馈q_reg[0]异或更新
        q_reg[21] <= q_reg[22] ^ q_reg[0];

        // bit21~bit3(q_reg[20:2]):中间无抽头区间,整体右移拷贝左侧高位原值
        q_reg[20:2] <= q_reg[21:3];

        // bit2(q_reg[1]):第二个抽头位,常规移位输入 q_reg[2] 异或全局反馈q_reg[0]更新
        q_reg[1] <= q_reg[2] ^ q_reg[0];

        // bit1(q_reg[0]):最低位抽头位,常规移位输入 q_reg[1] 异或全局反馈q_reg[0]更新
        q_reg[0] <= q_reg[1] ^ q_reg[0];
    end
end

// 连续赋值:内部寄存器状态直通输出端口,实时对外展示LFSR当前值
assign q = q_reg;

endmodule

输出结果

移位寄存器 -1

搭建下述电路:

参考答案

java 复制代码
/*
=====================================================================
顶层模块:4级串联D触发器 · 串行输入串行输出(SISO)移位寄存器
设计原理:4个带同步复位的D触发器首尾级联,单比特数据逐时钟向后传递
延迟特性:输入信号in经过4个完整时钟周期,从out端口输出,固定延迟4拍
复位方案:全局低电平同步复位resetn,仅时钟上升沿采样生效,复位全链路清零
适用场景:串行数据延时、比特流缓存、基础时序链路搭建
数据流路径:in → 第1级(q0) → 第2级(q1) → 第3级(q2) → 第4级(out)
=====================================================================
*/
module top_module (
    input clk,          // 全局同步时钟:全链路唯一时钟源,所有触发器统一在上升沿采样刷新数据
    input resetn,       // 低电平有效同步复位:仅时钟上升沿判定生效;拉低时4级触发器全部强制输出0
    input in,           // 单比特串行数据入口:待移位的原始比特信号,送入第1级触发器
    output out          // 单比特串行数据出口:第4级触发器输出,相对输入固定延迟4个时钟周期
);
    // 内部连线定义:承接前3级触发器输出结果,作为后一级触发器的数据输入端口
    // q0:第1级输出(延迟1拍);q1:第2级输出(延迟2拍);q2:第3级输出(延迟3拍)
    wire q0,q1,q2; 
    
    //----------------------------------------------------------------
    // 例化第1级D触发器:整条移位链路第一级,实现1时钟周期基础延迟
    // 输入:外部原始串行信号in;输出q0传递给下一级触发器
    //----------------------------------------------------------------
    dff_d dff_d0(
        .clk(clk),
        .resetn(resetn),
        .in(in),
        .out(q0)
    );
    //----------------------------------------------------------------
    // 例化第2级D触发器:接收前级q0,累计延迟2拍,输出q1向后传递
    //----------------------------------------------------------------
    dff_d dff_d1(
        .clk(clk),
        .resetn(resetn),
        .in(q0),
        .out(q1)
    );
    //----------------------------------------------------------------
    // 例化第3级D触发器:接收前级q1,累计延迟3拍,输出q2向后传递
    //----------------------------------------------------------------
    dff_d dff_d2(
        .clk(clk),
        .resetn(resetn),
        .in(q1),
        .out(q2)
    );
    //----------------------------------------------------------------
    // 例化第4级D触发器:链路最后一级,接收前级q2,累计延迟4拍直接对外输出out
    //----------------------------------------------------------------
    dff_d dff_d3(
        .clk(clk),
        .resetn(resetn),
        .in(q2),
        .out(out)
    );

endmodule

/*
=====================================================================
子模块:带低电平同步复位的上升沿D触发器(通用可复用基础单元)
核心时序规则:
1. 敏感列表仅保留posedge clk → 标准同步复位写法,复位信号不触发边沿,过滤高频毛刺误触发
2. resetn=0(复位有效):时钟上升沿强制输出清零,复位优先级高于正常数据寄存
3. resetn=1(正常工作):时钟上升沿采样输入in,更新输出out向后级传递
赋值规范:时序逻辑使用非阻塞赋值<=,规避多级级联仿真与综合结果不一致问题
=====================================================================
*/
module dff_d(  
    input clk,          // 触发器本地同步时钟,上升沿触发数据采样、状态刷新
    input resetn,       // 低电平同步复位控制信号:仅时钟上升沿判断是否执行清零操作
    input in,           // D端串行数据输入:本级触发器待锁存的单比特数据
    output reg out      // Q端寄存输出:reg型变量存储触发器时序状态,对外输出本级结果
);
    always @(posedge clk) begin
        // 同步复位分支:时钟上升沿到来且复位拉低,强制清空本级输出,阻断移位传递
        if(~resetn) begin
            out <= 1'b0;
        end 
        // 正常移位分支:复位释放,时钟沿采样输入in,锁存结果输出给后一级触发器
        else begin
            out <= in;
        end
    end
endmodule

输出结果

移位寄存器 -2

请参考下方所示的n位移位寄存器电路:

编写移位寄存器的顶层Verilog模块(模块名设为top_module),设定参数n = 4。在该顶层模块中例化4个MUXDFF子电路模块。假定此电路将在DE2开发板上实现。

• 将R输入端口连接至拨码开关SW,

• 时钟clk连接按键KEY0

• 使能端E连接按键KEY1

• 置数控制端L连接按键KEY2

• 输入信号w连接按键KEY3

• 输出信号连接红色LED灯LEDR3:0

(复用2014年试卷第四题a小问中你编写的MUXDFF模块。)

参考答案

java 复制代码
//=============================================================
// 模块名称:top_module
// 模块功能:4位多功能右移移位寄存器,支持并行加载、串行右移、数值保持三种工作模式
// 信号说明:
// SW[3:0]   4位拨码开关,提供并行加载的原始数据 R[3]~R[0]
// KEY[0]    全局同步时钟clk,所有触发器仅在时钟上升沿更新状态
// KEY[1]    移位使能信号E:E=1开启串行移位;E=0寄存器保持当前数值不变
// KEY[2]    并行加载控制信号L:全局最高优先级,L=1强制加载SW并行数据,屏蔽移位逻辑
// KEY[3]    串行输入端w,移位模式下从最高位灌入外部串行比特
// LEDR[3:0] 寄存器状态输出,位序 {q3,q2,q1,q0},q3为最高位、q0为最低位
// 移位方向:高位向低位逐级右移,数据流 KEY[3]→q3→q2→q1→q0
//=============================================================
module top_module (
    input  [3:0] SW,
    input  [3:0] KEY,
    output [3:0] LEDR
);
    // 内部连线:存储4级MUXDFF触发器各自的寄存输出
    // q3:最高位触发器输出;q0:最低位触发器输出
    wire q0,q1,q2,q3;

    //------------------------------
    // 例化第0级(最低位)触发器MUXDFF0
    // 移位输入w接相邻高位q1,接收上一级右移传来的数据
    // R接SW[0],并行加载时读取最低位拨码值
    //------------------------------
    MUXDFF MUXDFF0(
        .clk(KEY[0]),
        .E(KEY[1]),
        .L(KEY[2]),
        .w(q1),
        .Q(q0),
        .R(SW[0])
    );

    //------------------------------
    // 例化第1级(次低位)触发器MUXDFF1
    // 移位输入w接相邻高位q2,接收上一级右移传来的数据
    // R接SW[1],并行加载时读取对应拨码值
    //------------------------------
    MUXDFF MUXDFF1(
        .clk(KEY[0]),
        .E(KEY[1]),
        .L(KEY[2]),
        .w(q2),
        .Q(q1),
        .R(SW[1])
    );

    //------------------------------
    // 例化第2级(次高位)触发器MUXDFF2
    // 移位输入w接相邻高位q3,接收上一级右移传来的数据
    // R接SW[2],并行加载时读取对应拨码值
    //------------------------------
    MUXDFF MUXDFF2(
        .clk(KEY[0]),
        .E(KEY[1]),
        .L(KEY[2]),
        .w(q3),
        .Q(q2),
        .R(SW[2])
    );

    //------------------------------
    // 例化第3级(最高位)触发器MUXDFF3
    // 移位输入w接外部串行输入KEY[3],是整条移位链路的数据入口
    // R接SW[3],并行加载时读取最高位拨码值
    //------------------------------
    MUXDFF MUXDFF3(
        .clk(KEY[0]),
        .E(KEY[1]),
        .L(KEY[2]),
        .w(KEY[3]),
        .Q(q3),
        .R(SW[3])
    );

    // 组合逻辑连续赋值:按高低位顺序拼接4路触发器输出,驱动LED直观显示状态
    assign LEDR = {q3,q2,q1,q0};

endmodule

//=============================================================
// 模块名称:MUXDFF
// 模块功能:内置两级2选1多路选择器的多功能D触发器,单比特通用复用单元
// 控制优先级(从高到低):并行加载L > 移位使能E > 保持原值
// 通路逻辑分层:
// 第一级MUX:依据E选择「移位输入w」或「保持旧值Q」
// 第二级MUX:依据最高优先级L选择「并行数据R」或第一级MUX输出结果
// 时序规则:仅时钟上升沿锁存最终通路结果,全程同步时序,无异步控制毛刺
//=============================================================
module MUXDFF (
    input  clk,     // 同步时钟,上升沿触发寄存器采样更新
    input  w,       // 串行移位通路:单比特移位输入
    input  R,       // 并行加载通路:单比特并行预置输入
    input  E,       // 移位使能:控制移位/保持基础模式切换
    input  L,       // 并行加载开关:优先级最高,强制切入并行数据通路
    output reg Q    // 触发器寄存输出,reg型保存时序状态
);
    // 中间连线:两级多路选择器的过渡信号
    wire w1,w2;

    // 第一级2选1多路选择器:实现移位/保持切换
    // E=1:选择移位输入w,开启移位传递;E=0:锁存当前输出Q,数值保持不变
    assign w1 = E ? w : Q;

    // 第二级2选1多路选择器:叠加最高优先级并行加载控制
    // L=1:无视E状态,强制选用并行数据R;L=0:沿用第一级MUX的输出w1
    assign w2 = L ? R : w1;    

    // 同步时序逻辑块:敏感列表仅有时钟上升沿,标准同步寄存器建模写法
    always @(posedge clk) begin
        // 时钟上升沿,把两级MUX筛选后的最终值锁存到触发器输出Q
        Q <= w2; 
    end
    
endmodule

输出结果

3 输入LUT

本题要求你设计一块 8×1 存储电路:写入存储单元依靠逐位移入比特实现,读取方式则和普通随机存取存储器(RAM)一样,采用随机寻址。之后再用该存储电路实现一个三输入逻辑函数。

第一步:搭建由 8 个 D 触发器构成的 8 位移位寄存器。触发器输出命名为Q0 ~ Q7。移位寄存器的数据输入端命名为S,该端口接入Q0的输入(移位时最高比特 MSB 先移入)。增设使能端控制电路是否执行移位操作。

第二步:扩展电路,新增 3 路输入A、B、C与 1 路输出Z。电路逻辑规则如下: 寻址输入ABC为000时,输出Z = Q0;ABC为001时,输出Z = Q1; 以此类推(ABC 对应十进制 0~7,分别选择 Q 0~Q 7 输出到 Z)。

你的电路仅能包含:8 位移位寄存器、多路选择器(MUX)。 补充说明:该电路本质是三输入查找表(LUT)。

行为级建模参考答案

java 复制代码
/*
=====================================================================
模块功能:8位左移移位寄存器 + 3位地址8选1查表输出(LUT)组合电路
移位规则:使能有效时整体左移,新串行比特S写入最低位q[0],旧数据向高位递进
寻址规则:3位输入{A,B,C}直接作为索引,读取q对应位输出Z
工作模式:enable=1左移更新;enable=0寄存器保持原有数值不变
位序定义:q[7]最高位(MSB)、q[0]最低位(LSB),串行从低位移入、逐步推向高位
=====================================================================
*/
module top_module (
    input clk,          // 全局同步时钟:仅上升沿触发寄存器移位更新
    input enable,       // 移位使能(高有效):1=执行左移;0=寄存器锁存、保持数据不变
    input S,            // 串行单比特输入:移位时写入最低位q[0]
    input A, B, C,      // 3位寻址输入,拼接成索引 {A,B,C} 范围0~7,选中q其中1位
    output reg Z        // 查表输出:由多路组合逻辑读取寄存器指定位对外输出
);

// 8位移位寄存器存储阵列:q[7]最高位、q[0]最低位,保存串行移入的历史比特
reg [7:0] q;

//====================组合逻辑:8选1多路选择器查表输出====================
// 将独立3路地址信号A(高位)、B、C(低位)拼接成3位索引,直接选取q对应比特赋值Z
assign Z = q[ {A, B, C} ];

//====================时序逻辑:时钟上升沿控制左移操作====================
always @(posedge clk) begin
    if (enable) begin
        // 左移操作拆解:
        // 1.原低7位 q[6:0] 整体上移一位,填充 q[7:1]
        // 2.新串行输入S补充到最低位 q[0]
        // 数据流:S→q0→q1→...→q7,最早移入的比特最终停在最高位q7
        q <= {q[6:0], S};
    end
    // enable=0分支省略:时序块不赋值,寄存器默认保持上一拍状态,实现保持功能
end

endmodule

结构级建模参考答案

java 复制代码
/*
=====================================================================
顶层模块功能:8级串行移位存储阵列 + 3位地址8选1查表输出(LUT)
架构类型:结构级例化写法,复用单路muxdff基础单元逐级级联
移位流向:外部串行比特S → q0 → q1 → q2 → q3 → q4 → q5 → q6 → q7
控制规则:enable高电平开启逐拍移位;低电平所有单元锁存当前数值保持不变
寻址规则:3位地址{A,B,C}译码选中8路寄存器其中1路,组合逻辑实时输出Z
适用场景:串行比特流缓存、循环移位存储、多路随机查表读取
=====================================================================
*/
module top_module (
    input clk,      // 全局同步时钟,所有muxdff单元统一在时钟上升沿刷新寄存状态
    input enable,   // 全局移位使能(高电平有效):1=逐级移位;0=全部寄存器保持原值
    input S,        // 串行输入比特,送入移位链路第0级作为初始输入
    input A, B, C,  // 3位独立寻址信号,拼接为3bit索引,取值范围000~111对应q0~q7
    output reg Z    // 查表最终输出,组合逻辑随地址实时切换选中寄存器电平
);

// 内部连线:8级独立触发器输出节点,q0链路最低位、q7链路最高位
wire q0, q1, q2, q3, q4, q5, q6, q7;

// ====================== 8级移位寄存器(结构级逐单元例化) ======================
// 基础单元muxdff内置2选1MUX+D触发器,en控制移位/保持两种模式切换
// unit0:链路第1级,接收外部串行输入S,输出q0
muxdff unit0(.clk(clk), .shift_in(S),    .en(enable), .q_out(q0));
// unit1:链路第2级,接收前级q0,输出q1
muxdff unit1(.clk(clk), .shift_in(q0),   .en(enable), .q_out(q1));
// unit2:链路第3级,接收前级q1,输出q2
muxdff unit2(.clk(clk), .shift_in(q1),   .en(enable), .q_out(q2));
// unit3:链路第4级,接收前级q2,输出q3
muxdff unit3(.clk(clk), .shift_in(q2),   .en(enable), .q_out(q3));
// unit4:链路第5级,接收前级q3,输出q4
muxdff unit4(.clk(clk), .shift_in(q3),   .en(enable), .q_out(q4));
// unit5:链路第6级,接收前级q4,输出q5
muxdff unit5(.clk(clk), .shift_in(q4),   .en(enable), .q_out(q5));
// unit6:链路第7级,接收前级q5,输出q6
muxdff unit6(.clk(clk), .shift_in(q5),   .en(enable), .q_out(q6));
// unit7:链路末级,接收前级q6,输出q7,最早输入的比特最终移动至此
muxdff unit7(.clk(clk), .shift_in(q6),   .en(enable), .q_out(q7));

// ====================== 8选1多路选择器:组合逻辑随机寻址读取 ======================
always @(*) begin // *敏感列表:地址任意一路变化立刻更新输出,纯组合逻辑无延迟
    case ({A,B,C}) // A为索引高位、C为索引低位,3bit完整覆盖8个寄存器
        3'b000: Z = q0;
        3'b001: Z = q1;
        3'b010: Z = q2;
        3'b011: Z = q3;
        3'b100: Z = q4;
        3'b101: Z = q5;
        3'b110: Z = q6;
        3'b111: Z = q7;
        default: Z = q0; // 语法兜底分支,3位地址无越界场景,该分支实际不会触发
    endcase
end

endmodule

/*
=====================================================================
基础复用单元muxdff:内置2选1多路器+上升沿D触发器
双模式逻辑:
1.en=1:选移位输入shift_in,跟随前级数据正常移位传递
2.en=0:选自身输出q_out回灌输入端,触发器锁存数值、停止移位
时序规则:仅时钟上升沿采样d_in更新输出,全同步设计抗干扰强
=====================================================================
*/
module muxdff(
    input clk,
    input shift_in,  // 移位通路输入:外部串行S/上一级触发器输出
    input en,        // 移位使能控制信号,全局统一电平
    output reg q_out // 本级触发器寄存输出,向后级传递或自环保持
);
wire d_in; // D触发器端口输入,由多路选择器二选一得到

// 2选1多路选择器组合逻辑:切换移位通路/自环保持通路
assign d_in = en ? shift_in : q_out;

// 标准同步D触发器时序逻辑
always @(posedge clk) begin
    q_out <= d_in; // 时钟上升沿锁存多路器输出,更新本级状态
end

endmodule

输出结果

相关推荐
芯路行者2 小时前
4.2 HDLBits —— 时序逻辑电路之计数器
fpga开发·verilog·fpga·hdlbits
FPGA小迷弟7 小时前
FPGA时序收敛实战:从约束编写到布局布线优化全流程
fpga开发·fpga·硬件开发
FPGA小迷弟7 小时前
AXI4-Stream协议详解与Vivado自定义IP核封装实战
网络协议·tcp/ip·fpga开发·fpga·硬件开发
zlinear数据采集卡1 天前
数据采集卡从入门到精通(10):采样率与分辨率的核心关系——反比律、架构分布与过采样
arm开发·嵌入式硬件·算法·fpga开发·架构·开源
zlinear数据采集卡1 天前
数据采集卡从入门到精通(9):分辨率与精度——16位卡不等于1/65536的精度
开发语言·数据库·fpga开发·开源·c#
Hello-FPGA1 天前
AI 如何自动通过 PDF 原理图生成管脚映射
人工智能·fpga开发·pdf
zlinear数据采集卡1 天前
数据采集卡从入门到精通(7):流水线型ADC——级级接力,高速与高精的平衡术
开发语言·arm开发·嵌入式硬件·fpga开发·c#
鬼手点金2 天前
FPGA常用型号参考
fpga开发·verilog·vivado·xilinx·vhdl·altera·lattice
FPGA-ADDA2 天前
雷通微系统推出RTSD2605:RFSoC + 英伟达GPU一体化信号处理平台
信号处理·fpga·rfsoc·zu47dr·47dr