You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

4位数据1时钟周期并行移位Verilog实现正确性及FPGA可合成性问询

问题描述

需求:实现4位数据序列依次写入寄存器A、B、C,每级寄存器相对前一级延迟1个时钟周期。

以下是实现的Verilog设计代码:

module shift4bit(clock, data, out, outRegA, outRegB, outRegC);
input clock;
input [3:0] data;
output [3:0] out;
output [3:0] outRegA;
output [3:0] outRegB;
output [3:0] outRegC;

reg [3:0] RegA;
reg [3:0] RegB;
reg [3:0] RegC;

always @(posedge clock) begin
  RegA <= data;
  RegB <= RegA;
  RegC <= RegB;
end

assign out = data;
assign outRegA = RegA;
assign outRegB = RegB;
assign outRegC = RegC;

endmodule

对应的测试平台代码:

`timescale 1ns / 1ps

module shift4bit_tb; 

// Inputs
reg [3:0] data;
reg clock;
// Outputs
wire [3:0] out;
wire [3:0] outRegA;
wire [3:0] outRegB;
wire [3:0] outRegC;

// Instantiate the Unit Under Test (UUT)
shift4bit uut (.clock(clock),.data(data),.out(out),.outRegA(outRegA),.outRegB(outRegB),.outRegC(outRegC));

initial begin
  // Initialize Inputs
  data  = 4'b1111;
  clock  = 1'b1;
  // Wait 100 ns for global reset to finish
  #20;
  // Add stimulus here
  data = 4'b0001; #20;
  data = 4'b0010; #20;
  data = 4'b0011; #20;
  data = 4'b0100; #20;
  data = 4'b0101; #20;
  data = 4'b0110; #20;
  data = 4'b0111; #20;
  data = 4'b1000; #20;
end

always #10 clock = ~clock;  

endmodule

已得到仿真结果,显示存在预期的移位效果,现咨询:该代码逻辑是否正确?能否在FPGA上合成实现?


代码分析与结论

1. 逻辑正确性

代码完全符合需求:

  • 采用**非阻塞赋值<=**在时钟上升沿同步更新寄存器,保证每级寄存器的时序延迟:
    • 每个时钟上升沿,RegA捕获当前data的值;RegB捕获上一个时钟周期RegA的值;RegC捕获上一个时钟周期RegB的值。
    • 最终实现data → RegA(延迟1周期)→ RegB(延迟2周期)→ RegC(延迟3周期)的移位效果,和需求完全匹配。
  • 测试平台的时钟周期为20ns(每10ns翻转一次),data每20ns更新一次,刚好与时钟沿对齐,仿真结果能正确验证移位逻辑。

2. FPGA可合成性

该代码可以直接在FPGA上合成实现:

  • 代码使用的是FPGA工具完全支持的标准同步时序电路语法:always @(posedge clock)描述的寄存器、assign描述的组合逻辑,均属于可综合语法范畴。
  • 这种链式寄存器结构会被FPGA综合工具直接映射到器件内部的触发器资源,不存在合成障碍。

3. 工程优化建议(可选)

当前代码未包含复位逻辑,虽然不影响功能正确性,但在实际FPGA工程中,建议添加同步复位端口,用于初始化寄存器状态,避免上电后寄存器处于未知状态:

// 修改模块端口,添加复位信号
module shift4bit(clock, reset, data, out, outRegA, outRegB, outRegC);
input clock;
input reset; // 新增同步复位端口,高电平有效
input [3:0] data;
output [3:0] out;
output [3:0] outRegA;
output [3:0] outRegB;
output [3:0] outRegC;

reg [3:0] RegA;
reg [3:0] RegB;
reg [3:0] RegC;

always @(posedge clock) begin
  if(reset) begin
    RegA <= 4'b0000;
    RegB <= 4'b0000;
    RegC <= 4'b0000;
  end else begin
    RegA <= data;
    RegB <= RegA;
    RegC <= RegB;
  end
end

// 其余assign语句不变
assign out = data;
assign outRegA = RegA;
assign outRegB = RegB;
assign outRegC = RegC;

endmodule

内容的提问来源于stack exchange,提问作者Andy Ayr

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 12:53:14