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

如何在FPGA上实现类似MCU的寄存器写敏感操作?

在FPGA上实现MCU风格的写敏感寄存器行为

在部分微控制器(MCU)的外设中,存在写敏感和读敏感寄存器。例如串口的TX寄存器,对其执行写操作会触发相应动作。我希望在FPGA上实现相同的行为,以下是我的设计代码及用于展示预期行为的测试台,请问如何达成该预期行为?

module serial #(
    parameter DATA_WIDTH = 8
) (
    input [DATA_WIDTH-1:0] TX,
    input clk,
    output reg data_had_been_written
);

reg [DATA_WIDTH-1:0] tx_internal;

always @(TX) begin
    data_had_been_written <= 1;
    tx_internal <= TX; //this operation must be synchronized with posedge of clk, I hadn't do this to be more briefly.
end


always @(negedge clk) begin
    data_had_been_written <= 0;
end

endmodule

module tst_write_sensible;
parameter DATA_WIDTH = 8;

reg [DATA_WIDTH - 1:0] TX;
reg clk;
wire data_had_been_written;

serial s (
    .TX(TX),
    .clk(clk),
    .data_had_been_written(data_had_been_written)
);

initial begin
    clk = 0;
    for (int i = 0; i < 20; i = i + 1)
        #1 clk = ~clk;
end

initial begin
    #2 TX = 4; //Posedge of data_had_been_written must be triggered here
    #2 TX = 5; //Posedge of data_had_been_written must be triggered here
    #2 TX = 5; //Posedge of data_had_been_written must be triggered here
    #2 TX = 6; //Posedge of data_had_been_written must be triggered here
    #2 TX = 7; //Posedge of data_had_been_written must be triggered here
end

endmodule

问题分析

原代码存在两个核心问题:

  1. 异步逻辑风险:使用always @(TX)异步触发,FPGA中会引发亚稳态和信号毛刺,不符合同步设计规范。
  2. 重复写同值无法触发:当TX写入相同值时,always @(TX)不会执行,无法满足测试台中重复写同值也要触发data_had_been_written的需求。

解决方案

方案1:规范同步设计(支持值变化触发)

如果仅需要检测TX值变化时触发动作,采用两级寄存器同步输入,避免亚稳态,同时检测值变化生成同步脉冲:

module serial #(
    parameter DATA_WIDTH = 8
) (
    input [DATA_WIDTH-1:0] TX,
    input clk,
    output reg data_had_been_written
);

reg [DATA_WIDTH-1:0] tx_sync1;
reg [DATA_WIDTH-1:0] tx_sync2;
reg [DATA_WIDTH-1:0] tx_latched;

// 两级寄存器同步输入,消除亚稳态
always @(posedge clk) begin
    tx_sync1 <= TX;
    tx_sync2 <= tx_sync1;
end

// 检测TX值变化,触发动作并锁存数据
always @(posedge clk) begin
    if (tx_sync2 != tx_latched) begin
        tx_latched <= tx_sync2;
        data_had_been_written <= 1'b1;
    end else begin
        data_had_been_written <= 1'b0;
    end
end

endmodule

方案2:支持重复写同值(添加写使能信号)

若需要重复写同值也触发动作,需添加写使能信号(符合真实总线接口设计),通过写使能边沿检测触发动作:

module serial #(
    parameter DATA_WIDTH = 8
) (
    input [DATA_WIDTH-1:0] TX,
    input TX_WR,  // 写使能信号,上升沿有效
    input clk,
    output reg data_had_been_written
);

reg [DATA_WIDTH-1:0] tx_latched;
reg tx_wr_sync1;
reg tx_wr_sync2;

// 同步写使能信号
always @(posedge clk) begin
    tx_wr_sync1 <= TX_WR;
    tx_wr_sync2 <= tx_wr_sync1;
end

// 检测写使能上升沿,触发动作并锁存数据
always @(posedge clk) begin
    if (tx_wr_sync2 && !tx_wr_sync1) begin
        tx_latched <= TX;
        data_had_been_written <= 1'b1;
    end else begin
        data_had_been_written <= 1'b0;
    end
end

endmodule

对应修改测试台,添加写使能信号:

module tst_write_sensible;
parameter DATA_WIDTH = 8;

reg [DATA_WIDTH - 1:0] TX;
reg TX_WR;
reg clk;
wire data_had_been_written;

serial s (
    .TX(TX),
    .TX_WR(TX_WR),
    .clk(clk),
    .data_had_been_written(data_had_been_written)
);

initial begin
    clk = 0;
    for (int i = 0; i < 20; i = i + 1)
        #1 clk = ~clk;
end

initial begin
    TX_WR = 0;
    #2 TX = 4; TX_WR = 1; #1 TX_WR = 0;
    #1 TX = 5; TX_WR = 1; #1 TX_WR = 0;
    #1 TX = 5; TX_WR = 1; #1 TX_WR = 0; // 重复写同值依然触发
    #1 TX = 6; TX_WR = 1; #1 TX_WR = 0;
    #1 TX = 7; TX_WR = 1; #1 TX_WR = 0;
end

endmodule

方案3:适配原测试台(无写使能支持重复写)

如果必须基于原测试台逻辑,可利用TX赋值的时间规律(时钟negedge时刻赋值),在每个时钟周期生成同步脉冲:

module serial #(
    parameter DATA_WIDTH = 8
) (
    input [DATA_WIDTH-1:0] TX,
    input clk,
    output reg data_had_been_written
);

reg [DATA_WIDTH-1:0] tx_negedge_sample;

// 在时钟negedge采样TX值
always @(negedge clk) begin
    tx_negedge_sample <= TX;
end

// 在时钟posedge生成脉冲,对应每次TX赋值
always @(posedge clk) begin
    data_had_been_written <= 1'b1;
end

// 在时钟negedge清零脉冲
always @(negedge clk) begin
    data_had_been_written <= 1'b0;
end

endmodule

这个方案中,每个时钟周期的posedge会产生data_had_been_written脉冲,完全匹配原测试台的预期行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 05:27:08