资讯动态

Verilog基础:寄存器输出的两种风格

发布时间:2026/10/27 1:13:40 来源:尧图企业网站定制
相关文章Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482在Verilog设计中所谓“寄存器操作”通常指的是那些对时钟沿敏感并且使用非阻塞赋值完成更新的时序逻辑。例如寄存器加载、计数器递增、移位寄存器移位以及有限状态机中的状态转移等都可以看作寄存器操作。以状态机为例所谓状态转移本质上就是先由组合逻辑计算出“下一状态”再在时钟沿到来时把这个“下一状态”送入状态寄存器。因此从硬件结构上看这实际上就是“组合逻辑 寄存器”的典型连接方式如图1所示的Moore型状态机。图1 Moore型状态机对于状态机这类较为复杂的时序逻辑通常更推荐使用分离式写法。特别是常见的三段式状态机会把“下一状态组合逻辑”“状态寄存器更新逻辑”和“输出组合逻辑”明确拆开。这种写法层次分明因此在工程中被广泛接受。例如下面这种三段式描述方式//第一段下一状态组合逻辑 always(*) begin case (state) ***: next_state ***; ***: next_state ***; endcase end //第二段状态转移时序逻辑 always (posedge clk, negedge rst_n) begin if (!rst_n) state ***; else state next_state; end //第三段输出组合逻辑 always(*) begin if(state ***) out ***; else out ***; end当状态机不仅要完成状态转移还需要对输出信号进行寄存时就会出现两种不同的描述思路。一种思路是继续保持分离风格也就是把“输出组合逻辑”和“输出寄存逻辑”再拆成两段。另一种思路是直接把输出的组合计算和输出寄存融合在一起让时序逻辑块直接给输出寄存器赋值。下面分别来看。//将输出组合逻辑和输出寄存分离 //第一段下一状态组合逻辑 always(*) begin case (state) ***: next_state ***; ***: next_state ***; endcase end //第二段状态转移时序逻辑 always (posedge clk, negedge rst_n) begin if (!rst_n) state ***; else state next_state; end //第三段输出组合逻辑 always(*) begin if(state ***) out ***; else out ***; end //第四段输出寄存时序逻辑 always (posedge clk, negedge rst_n) begin if (!rst_n) out_r ***; else out_r out; end endmodule​ //将输出组合逻辑和输出寄存融合 //第一段下一状态组合逻辑 always(*) begin case (state) ***: next_state ***; ***: next_state ***; endcase end //第二段状态转移时序逻辑 always (posedge clk, negedge rst_n) begin if (!rst_n) state ***; else state next_state; end //第三段输出寄存时序逻辑 always (posedge clk, negedge rst_n) begin if (!rst_n) out_r ***; else out_r ***; end endmodule对于状态机简单的输出寄存可以将输出组合逻辑和输出寄存融合比如计数器对计数器而言状态就是输出所以也可以理解为将状态转移也融合进来了。同时对于一般简单的寄存器操作比如移位也可以将输出组合逻辑和输出寄存融合。//组合逻辑和寄存器操作融合 always(posedge clk or negedge rst_n) begin if(!rst_n) cnt 0; else cnt cnt 1; end //组合逻辑和寄存器操作不融合 always(posedge clk or negedge rst_n) begin if(!rst_n) cnt 0; else cnt cnt_pre; assign cnt_pre cnt 1; end //简单的寄存器操作组合逻辑和时序逻辑融合 always(posedge clk or negedge rst_n) begin if(!rst_n) shift 0; else if(load) shift shift_load; else shift shift 1; end //简单的寄存器操作组合逻辑和时序逻辑不融合 always(posedge clk or negedge rst_n) begin if(!rst_n) shift 0; else if(load) shift shift_load; else shift shift_pre; end assign shift_pre shift 1;从工程经验来看可以用一个比较实用的原则来判断复杂控制逻辑、复杂状态机优先分离简单寄存器更新、简单计数、简单移位优先融合如果某段逻辑已经复杂到需要额外解释它在做什么通常就应该考虑拆开写。换句话说写法选择的核心不是“教条地统一使用某一种风格”而是让代码在功能正确的前提下尽可能清晰、稳定、可维护。关于三段式状态机的更多内容可以看下面这篇博客。Verilog基础三段式状态机与输出寄存https://chenzhang.blog.csdn.net/article/details/134365162?spm1011.2415.3001.5331

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑