用图片做简单网站,c2c网站的类型,网站建设自查情况报告,建设通 建筑企业查询写在前面 在自己准备写一些简单的verilog教程之前#xff0c;参考了许多资料----Asic-World网站的这套verilog教程即是其一。这套教程写得极好#xff0c;奈何没有中文#xff0c;在下只好斗胆翻译过来#xff08;加点自己的理解#xff09;分享给大家。 这是网站原文参考了许多资料----Asic-World网站的这套verilog教程即是其一。这套教程写得极好奈何没有中文在下只好斗胆翻译过来加点自己的理解分享给大家。 这是网站原文Verilog Tutorial 这是系列导航Verilog教程系列文章导航 有限状态机FSM简介 状态机FSM是许多数字设计的核心。计数器就是 FSM 的一种简单形式。当我学习Verilog时我曾经想知道“如何在Verilog中编码FSM”和“编码它的最佳方法是什么”。接下来我将尝试回答这两个问题。
状态机类型 根据状态机的输出类型分类有两种类型的状态机。第一种是 Moore 状态机其输出仅是当前状态的函数第二种是 Mealy 状态机其输出是当前状态和输入的函数。
Moore 状态机 Mealy 状态机 状态机还可以根据所使用的状态编码进行分类。编码类型也是决定FSM的速度和复杂度的关键因素。二进制编码、格雷码、独热码是最常见的几种 FSM 状态编码类型。
状态机建模 编码 FSM 时需要记住的一件事组合逻辑和时序逻辑应该位于两个不同的always块中。在上两图中下一状态逻辑next state logic始终是组合逻辑而状态逻辑state logic和输出逻辑output logic则是时序逻辑。任何到下一个状态逻辑的异步信号在馈送到 FSM 之前都必须进行同步化处理。你应该尽量将状态机FSM 保存在单独的 Verilog 文件中。 使用parameter或define 等常量声明来定义 FSM 的状态可使代码更具可读性且更易于管理。
示例仲裁器 接下来将以仲裁器作为案例看看该如何实现一个完整的FSM。 FSM 代码应包含三个部分
状态编码部分组合逻辑部分时序逻辑部分
状态编码 状态编码有许多方式其中最常用的是
二进制码Binary Encoding独热码One Hot Encoding格雷码Gray Encoding 独热码One Hot Encoding
parameter [4:0] IDLE 5b0_0001;
parameter [4:0] GNT0 5b0_0010;
parameter [4:0] GNT1 5b0_0100;
parameter [4:0] GNT2 5b0_1000;
parameter [4:0] GNT3 5b1_0000;
二进制码Binary Encoding
parameter [2:0] IDLE 3b000;
parameter [2:0] GNT0 3b001;
parameter [2:0] GNT1 3b010;
parameter [2:0] GNT2 3b011;
parameter [2:0] GNT3 3b100;
格雷码Gray Encoding
parameter [2:0] IDLE 3b000;
parameter [2:0] GNT0 3b001;
parameter [2:0] GNT1 3b011;
parameter [2:0] GNT2 3b010;
parameter [2:0] GNT3 3b110; 组合逻辑部分 这一部分可以使用函数、assign 语句或者always块来实现。
always (state or req_0 or req_1 or req_2 or req_3)
begin next_state 0;case(state)IDLE : if (req_0 1b1) beginnext_state GNT0;end else if (req_1 1b1) beginnext_state GNT1;end else if (req_2 1b1) beginnext_state GNT2;end else if (req_3 1b1) beginnext_state GNT3;end else beginnext_state IDLE;end GNT0 : if (req_0 1b0) beginnext_state IDLE;end else beginnext_state GNT0;endGNT1 : if (req_1 1b0) beginnext_state IDLE;end else beginnext_state GNT1;endGNT2 : if (req_2 1b0) beginnext_state IDLE;end else beginnext_state GNT2;endGNT3 : if (req_3 1b0) beginnext_state IDLE;end else beginnext_state GNT3;enddefault : next_state IDLE;endcase
end
时序逻辑部分 这一部分只能使用边沿敏感逻辑例如带posedge clock或者negedge clock的always块来实现。
always (posedge clock)
begin : OUTPUT_LOGICif (reset 1b1) begingnt_0 #1 1b0;gnt_1 #1 1b0;gnt_2 #1 1b0;gnt_3 #1 1b0;state #1 IDLE;end else beginstate #1 next_state;case(state)IDLE : begingnt_0 #1 1b0;gnt_1 #1 1b0;gnt_2 #1 1b0;gnt_3 #1 1b0;endGNT0 : begingnt_0 #1 1b1;endGNT1 : begingnt_1 #1 1b1;endGNT2 : begingnt_2 #1 1b1;endGNT3 : begingnt_3 #1 1b1;enddefault : beginstate #1 IDLE;endendcaseend
end
使用二进制编码的完整FSM代码
module fsm_full(
clock , // Clock
reset , // Active high reset
req_0 , // Active high request from agent 0
req_1 , // Active high request from agent 1
req_2 , // Active high request from agent 2
req_3 , // Active high request from agent 3
gnt_0 , // Active high grant to agent 0
gnt_1 , // Active high grant to agent 1
gnt_2 , // Active high grant to agent 2
gnt_3 // Active high grant to agent 3
);
// Port declaration here
input clock ; // Clock
input reset ; // Active high reset
input req_0 ; // Active high request from agent 0
input req_1 ; // Active high request from agent 1
input req_2 ; // Active high request from agent 2
input req_3 ; // Active high request from agent 3
output gnt_0 ; // Active high grant to agent 0
output gnt_1 ; // Active high grant to agent 1
output gnt_2 ; // Active high grant to agent 2
output gnt_3 ; // Active high grant to agent // Internal Variables
reg gnt_0 ; // Active high grant to agent 0
reg gnt_1 ; // Active high grant to agent 1
reg gnt_2 ; // Active high grant to agent 2
reg gnt_3 ; // Active high grant to agent parameter [2:0] IDLE 3b000;
parameter [2:0] GNT0 3b001;
parameter [2:0] GNT1 3b010;
parameter [2:0] GNT2 3b011;
parameter [2:0] GNT3 3b100;reg [2:0] state, next_state;always (state or req_0 or req_1 or req_2 or req_3)
begin next_state 0;case(state)IDLE : if (req_0 1b1) beginnext_state GNT0;end else if (req_1 1b1) beginnext_state GNT1;end else if (req_2 1b1) beginnext_state GNT2;end else if (req_3 1b1) beginnext_state GNT3;end else beginnext_state IDLE;end GNT0 : if (req_0 1b0) beginnext_state IDLE;end else beginnext_state GNT0;endGNT1 : if (req_1 1b0) beginnext_state IDLE;end else beginnext_state GNT1;endGNT2 : if (req_2 1b0) beginnext_state IDLE;end else beginnext_state GNT2;endGNT3 : if (req_3 1b0) beginnext_state IDLE;end else beginnext_state GNT3;enddefault : next_state IDLE;endcase
endalways (posedge clock)
begin : OUTPUT_LOGICif (reset) begingnt_0 #1 1b0;gnt_1 #1 1b0;gnt_2 #1 1b0;gnt_3 #1 1b0;state #1 IDLE;end else beginstate #1 next_state;case(state)IDLE : begingnt_0 #1 1b0;gnt_1 #1 1b0;gnt_2 #1 1b0;gnt_3 #1 1b0;endGNT0 : begingnt_0 #1 1b1;endGNT1 : begingnt_1 #1 1b1;endGNT2 : begingnt_2 #1 1b1;endGNT3 : begingnt_3 #1 1b1;enddefault : beginstate #1 IDLE;endendcaseend
endendmodule
测试脚本
include fsm_full.vmodule fsm_full_tb();
reg clock , reset ;
reg req_0 , req_1 , req_2 , req_3;
wire gnt_0 , gnt_1 , gnt_2 , gnt_3 ;initial begin$display(Time\t R0 R1 R2 R3 G0 G1 G2 G3);$monitor(%g\t %b %b %b %b %b %b %b %b, $time, req_0, req_1, req_2, req_3, gnt_0, gnt_1, gnt_2, gnt_3);clock 0;reset 0;req_0 0;req_1 0;req_2 0;req_3 0;#10 reset 1;#10 reset 0;#10 req_0 1;#20 req_0 0;#10 req_1 1;#20 req_1 0;#10 req_2 1;#20 req_2 0;#10 req_3 1;#20 req_3 0;#10 $finish;
endalways#2 clock ~clock;fsm_full U_fsm_full(
clock , // Clock
reset , // Active high reset
req_0 , // Active high request from agent 0
req_1 , // Active high request from agent 1
req_2 , // Active high request from agent 2
req_3 , // Active high request from agent 3
gnt_0 , // Active high grant to agent 0
gnt_1 , // Active high grant to agent 1
gnt_2 , // Active high grant to agent 2
gnt_3 // Active high grant to agent 3
);endmodule 仿真结果 您有任何问题都可以在评论区和我交流本文由 孤独的单刀 原创首发于CSDN平台博客主页wuzhikai.blog.csdn.net您的支持是我持续创作的最大动力如果本文对您有帮助还请多多点赞、评论和收藏⭐