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

相关文章

Verilog基础icon-default.png?t=N7T8https://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;

相关推荐

  1. Lumeical Script------Script Prompt 中输出方式

    2023-12-10 07:24:03       57 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-10 07:24:03       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-10 07:24:03       101 阅读
  3. 在Django里面运行非项目文件

    2023-12-10 07:24:03       82 阅读
  4. Python语言-面向对象

    2023-12-10 07:24:03       91 阅读

热门阅读

  1. layui

    layui

    2023-12-10 07:24:03      41 阅读
  2. 山西教资面试---结构化真题125道

    2023-12-10 07:24:03       44 阅读
  3. Android 设置20点触摸

    2023-12-10 07:24:03       54 阅读
  4. 前端知识笔记(二)———Django与Ajax

    2023-12-10 07:24:03       53 阅读
  5. qml刷新C++中的QImage图像

    2023-12-10 07:24:03       63 阅读