查看: 1137|回复: 0
收起左侧

【FPGA】Verilog状态机设计

[复制链接]

  离线 

  • TA的每日心情
    拍拍
    2022-6-27 11:09
  • 签到天数: 25 天

    [LV.4]

    发表于 2021-3-16 22:33:57 | 显示全部楼层 |阅读模式

    有人预言,RISC-V或将是继Intel和Arm之后的第三大主流处理器体系。欢迎访问全球首家只专注于RISC-V单片机行业应用的中文网站

    您需要 登录 才可以下载或查看,没有帐号?立即注册

    x
    本帖最后由 sky 于 2021-3-16 22:33 编辑

    状态机是fpga设计中极其重要的一种技巧,掌握状态机的写法可以使fpga的开发事半功倍。

    下面记录一下状态机的基本知识理论。
    .
    国内芯片技术交流-【FPGA】Verilog状态机设计risc-v单片机中文社区(1)

    国内芯片技术交流-【FPGA】Verilog状态机设计risc-v单片机中文社区(2)


    实例:

    国内芯片技术交流-【FPGA】Verilog状态机设计risc-v单片机中文社区(3)


    三种状态机实现代码:

    1. // 一段式状态机

    2. module style1_fsm(i_clk, rst_n, i1, i2, o1, o2, err);

    3. input i_clk, rst_n, i1, i2;
    4. output o1, o2, err;

    5. parameter [3:0] IDLE = 4'b0001,
    6.                 S1   = 4'b0010,
    7.                 S2   = 4'b0100,
    8.                 ERROR= 4'b1000;

    9. reg o1, o2, err;
    10. reg [3:0] state;

    11. always @(posedge i_clk or negedge rst_n)
    12. begin
    13.         if(!rst_n) begin
    14.                 state <= IDLE;
    15.                 {o1, o2, err} <= 3'b000;
    16.         end
    17.         else
    18.                 case(state)
    19.                 IDLE:        begin
    20.                                 if(!i1) begin
    21.                                         {o1, o2, err} <= 3'b000;
    22.                                         state <= IDLE;
    23.                                 end
    24.                                 if(i1 & i2) begin                                       
    25.                                         {o1, o2, err} <= 3'b100;
    26.                                         state <= S1;
    27.                                 end
    28.                                 if(i1 & !i2) begin                                       
    29.                                         {o1, o2, err} <= 3'b111;
    30.                                         state <= ERROR;
    31.                                 end
    32.                         end
    33.                 S1:        begin
    34.                                 if(!i2) begin                                       
    35.                                         {o1, o2, err} <= 3'b100;
    36.                                         state <= S1;
    37.                                 end
    38.                                 if(i1 & i2) begin                                       
    39.                                         {o1, o2, err} <= 3'b010;
    40.                                         state <= S2;
    41.                                 end
    42.                                 if(!i1 & i2) begin                                       
    43.                                         {o1, o2, err} <= 3'b111;
    44.                                         state <= ERROR;
    45.                                 end
    46.                         end
    47.                 S2:        begin
    48.                                 if(i2) begin                                       
    49.                                         {o1, o2, err} <= 3'b010;
    50.                                         state <= S2;
    51.                                 end
    52.                                 if(i1 & !i2) begin                                       
    53.                                         {o1, o2, err} <= 3'b000;
    54.                                         state <= IDLE;
    55.                                 end
    56.                                 if(!i1 & !i2) begin                                       
    57.                                         {o1, o2, err} <= 3'b111;
    58.                                         state <= ERROR;
    59.                                 end
    60.                         end
    61.                 ERROR:        begin
    62.                                 if(i1) begin                                       
    63.                                         {o1, o2, err} <= 3'b111;
    64.                                         state <= ERROR;
    65.                                 end
    66.                                 if(!i1) begin                                       
    67.                                         {o1, o2, err} <= 3'b000;
    68.                                         state <= IDLE;
    69.                                 end
    70.                         end
    71.                 default:begin                                
    72.                                 {o1, o2, err} <= 3'b000;
    73.                                 state <= IDLE;
    74.                         end
    75.                 endcase

    76. end


    77. endmodule
    复制代码
    1. // 两段式状态机

    2. module style2_fsm(i_clk, rst_n, i1, i2, o1, o2, err);

    3. input i_clk, rst_n, i1, i2;
    4. output o1, o2, err;

    5. parameter [3:0] IDLE = 4'b0001,
    6.                 S1   = 4'b0010,
    7.                 S2   = 4'b0100,
    8.                 ERROR= 4'b1000;

    9. reg o1, o2, err;
    10. reg [3:0] curr_state, next_state;

    11. always @(posedge i_clk or negedge rst_n) begin
    12.         if(!rst_n)
    13.                 curr_state <= IDLE;
    14.         else
    15.                 curr_state <= next_state;
    16. end

    17. always @(curr_state or i1 or i2) begin
    18.         case(curr_state)
    19.         IDLE:        begin
    20.                         if(!i1) begin
    21.                                 IDLE_OUT;
    22.                                 next_state = IDLE;
    23.                         end
    24.                         if(i1 & i2) begin
    25.                                 S1_OUT;
    26.                                 next_state = S1;
    27.                         end
    28.                         if(i1 & !i2) begin
    29.                                 ERROR_OUT;
    30.                                 next_state = ERROR;
    31.                         end
    32.                 end
    33.         S1:        begin
    34.                         if(!i2) begin
    35.                                 S1_OUT;
    36.                                 next_state = S1;
    37.                         end
    38.                         if(!i1 & i2) begin
    39.                                 ERROR_OUT;
    40.                                 next_state = ERROR;
    41.                         end
    42.                         if(i1 & i2) begin
    43.                                 S2_OUT;
    44.                                 next_state = S2;
    45.                         end
    46.                 end
    47.         S2:        begin
    48.                         if(i2) begin
    49.                                 S2_OUT;
    50.                                 next_state = S2;
    51.                         end
    52.                         if(i1 & !i2) begin
    53.                                 IDLE_OUT;
    54.                                 next_state = IDLE;
    55.                         end
    56.                         if(!i1 & !i2) begin
    57.                                 ERROR_OUT;
    58.                                 next_state = ERROR;
    59.                         end
    60.                 end
    61.         ERROR:        begin
    62.                         if(i1) begin
    63.                                 ERROR_OUT;
    64.                                 next_state = ERROR;
    65.                         end
    66.                         if(!i1) begin
    67.                                 IDLE_OUT;
    68.                                 next_state = IDLE;
    69.                         end
    70.                 end
    71.         default:begin
    72.                         IDLE_OUT;
    73.                         next_state <= IDLE;
    74.                 end
    75.         endcase
    76. end

    77. task IDLE_OUT;
    78.         {o1, o2, err} = 3'b000;
    79. endtask

    80. task S1_OUT;
    81.         {o1, o2, err} = 3'b100;
    82. endtask

    83. task S2_OUT;
    84.         {o1, o2, err} = 3'b010;
    85. endtask

    86. task ERROR_OUT;
    87.         {o1, o2, err} = 3'b111;
    88. endtask

    89. endmodule
    复制代码
    1. // 三段式状态机

    2. module style3_fsm(i_clk, rst_n, i1, i2, o1, o2, err);

    3. input i_clk, rst_n, i1, i2;
    4. output o1, o2, err;

    5. parameter [3:0] IDLE = 4'b0001,
    6.                 S1   = 4'b0010,
    7.                 S2   = 4'b0100,
    8.                 ERROR= 4'b1000;

    9. reg o1, o2, err;
    10. reg [3:0] curr_state, next_state;

    11. always @(posedge i_clk or negedge rst_n)
    12. begin
    13.         if(!rst_n)
    14.                 curr_state <= IDLE;
    15.         else
    16.                 curr_state <= next_state;
    17. end

    18. always @(curr_state or i1 or i2)
    19. begin        
    20.         case(curr_state)
    21.         IDLE:        begin
    22.                         if(!i1)                next_state = IDLE;
    23.                         if(i1 & i2)        next_state = S1;
    24.                         if(i1 & !i2)        next_state = ERROR;
    25.                 end
    26.         S1:        begin
    27.                         if(!i2)                next_state = S1;
    28.                         if(i1 & i2)        next_state = S2;
    29.                         if(!i1 & i2)        next_state = ERROR;
    30.                 end
    31.         S2:        begin
    32.                         if(i2)                next_state = S2;
    33.                         if(i1 & !i2)        next_state = IDLE;
    34.                         if(!i1 & !i2)        next_state = ERROR;
    35.                 end
    36.         ERROR:        begin
    37.                         if(i1)                next_state = ERROR;
    38.                         if(!i1)                next_state = IDLE;
    39.                 end
    40.         default:begin
    41.                         next_state = IDLE;        // 不加这个default项 输出会一直是000!!!
    42.                 end
    43.         endcase
    44. end

    45. always @(posedge i_clk or negedge rst_n)
    46. begin
    47.         if(!rst_n)
    48.                 {o1, o2, err} <= 3'b000;
    49.         else begin
    50.                 case(next_state)
    51.                 IDLE:        {o1, o2, err} <= 3'b000;
    52.                 S1:        {o1, o2, err} <= 3'b100;
    53.                 S2:        {o1, o2, err} <= 3'b010;
    54.                 ERROR:        {o1, o2, err} <= 3'b111;
    55.                 default:{o1, o2, err} <= 3'b000;//不加这个default 复位前信号都为不定值X
    56.                 endcase
    57.         end
    58. end



    59. endmodule
    复制代码








    上一篇:RISC-V的研发成功,将给嵌入式ARM带来冲击
    下一篇:世界正为中国南方这家工厂焦虑
    RISCV作者优文
    全球首家只专注于RISC-V单片机行业应用的中文网站
    回复

    使用道具 举报

    高级模式
    B Color Image Link Quote Code Smilies

    本版积分规则

    关闭

    RISC-V单片机中文网上一条 /2 下一条



    版权及免责声明|RISC-V单片机中文网 |网站地图

    GMT+8, 2024-3-29 03:05 , Processed in 0.553677 second(s), 48 queries .

    快速回复 返回顶部 返回列表