Verilog基础:寄存器输出的两种风格
2023-12-13 04:19:26
相关文章
Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm=1001.2014.3001.5482
? ? ? ? Verilog中的寄存器操作一般指的是那些对时钟沿敏感而且使用非阻塞赋值的操作。例如状态机中的状态转移,实际上就是一种寄存器操作,因为这相当于将下一状态的组合逻辑连接至寄存器的输入,如图一的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;
文章来源:https://blog.csdn.net/weixin_45791458/article/details/134900026
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!