时间:2023年12月1日15点02分
截止到目前为止,基础的逻辑组合电路和时序电路都已经结束。下面开始状态机的学习。
引言
在学习状态机之前我们先提几个问题:
1.为啥要学状态机:
答:通过前面章节的学习我们都知道FPGA 是并行执行的,如果我们想要处理具有前后顺序的事件该怎么办呢?这时就需要引入状态机了。
2.什么是独热码?
独热码(One-Hot Encoding)是一种常用的数据编码技术,用于将离散的分类变量转换为二进制向量。
在独热编码中,如果有n个不同的类别,那么每个类别将被表示为一个长度为n的二进制向量,只有对应类别的索引位置上的元素为1,其他位置上的元素都为0。这样,每个类别都有唯一对应的二进制编码。
例如,假设有三个类别:猫、狗和鸟。使用独热编码,猫可以表示为[1, 0, 0],狗可以表示为[0, 1, 0],而鸟可以表示为[0, 0, 1]。
独热编码在机器学习和数据分析中被广泛应用,特别是在处理分类变量时。它将离散的分类变量转换为数值向量,以便更好地适应机器学习算法的要求。通过独热编码,模型可以更好地理解和处理类别之间的关系,而不会引入错误的数值关系。
3:Moore 状态机和Mealy 状态机
Moore状态机和Mealy状态机是两种常见的有限状态机模型,用于描述离散事件系统的行为。
首先,让我们先来了解一下有限状态机(FSM)。FSM是一种数学模型,用于描述系统在不同状态下接收和处理输入,并根据输入的不同转移到不同的状态。FSM由一组状态、一组输入和输出信号以及状态转换规则组成。
Moore状态机以数学家Edward F. Moore的名字命名,其特点是输出仅与当前状态相关。在Moore状态机中,每个状态都有一个固定的输出,不受输入的影响。当系统接收到输入时,它根据当前状态进行状态转换,并在进入下一个状态后产生输出。换句话说,输出是与状态直接相关的。
Mealy状态机以设计者George H. Mealy的名字命名,与Moore状态机不同,其特点是输出与当前状态和输入相关。在Mealy状态机中,每个状态都有一个与输入相关的输出。当系统接收到输入时,它根据当前状态和输入进行状态转换,并在进入下一个状态前产生输出。换句话说,输出是与状态和输入相关的。
总结一下:
- Moore状态机:输出仅与当前状态相关。
- Mealy状态机:输出与当前状态和输入相关。
这两种状态机在不同的应用中有着不同的使用场景。选择使用哪种状态机取决于系统的需求和设计目标。
4:状态机的一段式、二段式、三段式设计各有何优缺点
在状态机设计中,一段式、二段式和三段式是常见的三种设计方法。它们在组织状态之间的转换和对输入的处理方式上有所不同。
-
一段式设计:
在一段式设计中,状态转换和输入处理都集中在一个模块中。整个状态机的逻辑由一个大的代码块实现。一段式设计简单直接,适用于小规模的状态机和简单的应用场景。它的优点是结构简单,易于理解和实现。缺点是当状态机增长复杂时,代码容易变得冗长、难以维护和扩展。 -
二段式设计:
在二段式设计中,状态转换和输入处理分别由两个模块实现。状态转换模块负责管理状态转换逻辑,而输入处理模块负责处理输入信号并触发状态转换。二段式设计将状态转换和输入处理分开,提高了模块化和可复用性。它的优点是结构清晰,易于维护和扩展。缺点是增加了系统的复杂性和开销,需要更多的模块和通信机制。 -
三段式设计:
在三段式设计中,状态转换、输入处理和输出生成分别由三个独立的模块实现。状态转换模块负责管理状态转换逻辑,输入处理模块负责处理输入信号,而输出生成模块负责生成输出信号。三段式设计进一步提高了模块化和可复用性,使系统更加灵活和可扩展。它的优点是模块之间的隔离性强,易于测试和维护。缺点是增加了系统的复杂性和开销,需要更多的模块和通信机制。
选择哪种设计方法取决于具体的应用场景和设计需求。一段式设计适用于简单的状态机和小规模应用,二段式和三段式设计适用于复杂的状态机和大规模应用。在设计过程中,需要综合考虑系统的复杂性、可维护性、扩展性以及开发和测试的成本。
让我们看看野火FPGA是如何描述新二段式状态机的
老的一段式、二段式、三段式各有优缺点,其中一段式在描述大型状态机时会比较困难,会使整个系统显得十分臃肿,不够清晰;二段式状态机的好处是其结构和理想的理论模型完全吻合,即不会有附加的结构存在,比较精简,但是由于二段状态机的第二段是组合逻辑描述数据的输出,所以有一些情况是无法描述的,比如输出时需要类似计数的累加情况,这种情况在组合逻辑中会产生自迭代,自迭代在组合逻辑电路中是严格禁止的,而且第二段状态机主要是描述数据的输出,输出时使用组合逻辑往往会产生更多的毛刺,所以并不推荐。所以衍生出三段式状态机,三段状态机的输出就可是时序逻辑了,但是其结构并不是最精简的了。三段式状态机的第一段状态机是用时序逻辑描述当前状态,第二段状态机是用组合逻辑描述下一状态,如果把这两个部分进行合并而第三段状态机保持不变,就是我们现在最新的二段式状态机了。这种新的写法在现在不同综合器中都可以被识别出来,这样既消除了组合逻辑可能产生的毛刺,又减小了代码量,还更加容易上手,不必再去关心理论模型是怎样的,仅仅根据状态转移图就非常容易实现,对初学者来说十分友好。所以我们习惯性的使用两个均采用时序逻辑的 always 块,第一个 always 块描述状态的转移为第一段状态机,第二个 always 块描述数据的输出为第二段状态机(如果我们遵循一个 always 块只描述一个变量的原则,如果有多个输出时第二段状态机就可以分为多个always 块来表达,但理论上仍属于新二段状态机,所以几段式状态机并不是由 always 块的数量简单决定的)。
FMS (Finite State Machine)
Simple FMS 1(Asynchronous reset)
这题我也是使用的新二段式状态机进行代码的编写
module top_module(
input clk,
input areset, // Asynchronous reset to state B
input in,
output out);//
//只有两种状态,使用独热码,有种宏定义的感觉A代表0,B代表1
parameter A=0;
parameter B=1;
reg state, next_state;
always @(posedge clk or posedge areset) begin // 第一段只描述输入和状态之间的关系
if(areset == 1'b1)
state <= B;
else case(state)
A : if(in == 1'b1)
state <= A;
else
state <= B;
B : if(in == 1'b1)
state <= B;
else
state <= A;
default : state <= B;
endcase
end
always @(posedge clk or posedge areset) begin // 第二段描述状态和输入对输出的影响
if(areset == 1'b1)
out <= 1'b1;
else if((state == A) && (in == 1'b1))
out <= 1'b0;
else if((state == A) && (in == 1'b0))
out <= 1'b1;
else if((state == B) && (in == 1'b10))
out <= 1'b0;
else if((state == B) && (in == 1'b1))
out <= 1'b1;//
end
endmodule
Fsm1s
没什么难的嘛,同步复位而已,稍微修改下上面的代码就好了嘛
// Note the Verilog-1995 module declaration syntax here:
module top_module(clk, reset, in, out);
input clk;
input reset; // Synchronous reset to state B
input in;
output out;// 这儿我是有疑问的可以这样写代码吗,不要用括号括起来吗
reg out;
// Fill in state name declarations
parameter A=0;
parameter B=1;
reg state, next_state;
always @(posedge clk) begin // 第一段只描述输入和状态之间的关系
if(reset == 1'b1)
state <= B;
else case(state)
A : if(in == 1'b1)
state <= A;
else
state <= B;
B : if(in == 1'b1)
state <= B;
else
state <= A;
default : state <= B;
endcase
end
always @(posedge clk) begin // 第二段描述状态和输入对输出的影响
if(reset == 1'b1)
out <= 1'b1;
else if((state == A) && (in == 1'b1))
out <= 1'b0;
else if((state == A) && (in == 1'b0))
out <= 1'b1;
else if((state == B) && (in == 1'b10))
out <= 1'b0;
else if((state == B) && (in == 1'b1))
out <= 1'b1;//
end
endmodule
Fsm2
module top_module(
input clk,
input areset, // Asynchronous reset to OFF
input j,
input k,
output out); //
parameter OFF=0, ON=1;
reg state, next_state;
always @(posedge clk or posedge areset) begin // 第一段只描述输入和状态之间的关系
if(areset == 1'b1)
state <= OFF;
else case(state)
OFF : if(j == 1'b0)
state <= OFF;
else
state <= ON;
ON : if(k == 1'b0)
state <= ON;
else
state <= OFF;
default : state <= OFF;
endcase
end
always @(posedge clk or posedge areset) begin // 第二段描述状态和输入对输出的影响
if(areset == 1'b1)
out <= 1'b0;
else if((state == OFF) && (j == 1'b0))
out <= 1'b0;
else if((state == OFF) && (j == 1'b1))
out <= 1'b1;
else if((state == ON) && (k == 1'b0))
out <= 1'b1;
else if((state == ON) && (k == 1'b1))
out <= 1'b0;//
end
endmodule
Fsm3comb
兵无常势,水无常形,不要局限在三段式或者两段式状态机中无法自拔。这段代码,两个字,简洁。
module top_module(
input in,
input [1:0] state,
output [1:0] next_state,
output out); //
parameter A=2'd0, B=2'd1, C=2'd2, D=2'd3;
// State transition logic: next_state = f(state, in)
always@* begin
case(state)
A:next_state=in?B:A;
B:next_state=in?B:C;
C:next_state=in?D:A;
D:next_state=in?B:C;
endcase
end
// Output logic: out = f(state) for a Moore state machine
assign out = (state == D);
endmodule
Fsm3onehot
module top_module(
input in,
input [3:0] state,
output [3:0] next_state,
output out); //
parameter A=0, B=1, C=2, D=3;
// State transition logic: Derive an equation for each state flip-flop.
assign next_state[A] = state[0]&(~in) | state[2]&(~in);
assign next_state[B] = (state[0]|state[1]|state[3])&(in);
assign next_state[C] = state[1]&(~in) | state[3]&(~in);
assign next_state[D] = state[2]∈
// Output logic:
assign out = state[D];
endmodule
Fsm3
重读这段话:
在Moore状态机中,每个状态都有一个固定的输出,不受输入的影响。当系统接收到输入时,它根据当前状态进行状态转换,并在进入下一个状态后产生输出。换句话说,输出是与状态直接相关的。——输出是与状态相关,但是与下一个状态相关!!!所以,它是在当前状态为C且输入为1时,输出为1.
请看状态转移图
module top_module(
input clk,
input in,
input areset,
output out); //
parameter A=4'b0001;
parameter B=4'b0010;
parameter C=4'b0100;
parameter D=4'b1000;
reg [3:0] state;
always @(posedge clk or posedge areset) begin // 第一段只描述输入和状态之间的关系
if(areset == 1'b1)
state <= A;
else case(state)
A : if(in == 1'b0)
state <= A;
else
state <= B;
B : if(in == 1'b0)
state <= C;
else
state <= B;
C : if(in == 1'b0)
state <= A;
else
state <= D;
D : if(in == 1'b0)
state <= C;
else
state <= B;
default : state <= A;
endcase
end
always @(posedge clk or posedge areset) begin // 第二段描述状态和输入对输出的影响
if(areset == 1'b1)
out <= 1'b0;
else if(state == C & in==1) //我找了好久的错误,思虑了好久,没想到它不是在状态为D的时候输出1,而是在下个状态为D的时候输出1
out <= 1'b1;
else
out <= 1'b0;
end
endmodule
Fsm3s
没什么难的只是将异步复位改成同步复位了而已。
module top_module(
input clk,
input in,
input reset,
output out); //
parameter A=4'b0001;
parameter B=4'b0010;
parameter C=4'b0100;
parameter D=4'b1000;
reg [3:0] state;
always @(posedge clk ) begin // 第一段只描述输入和状态之间的关系
if(reset == 1'b1)
state <= A;
else case(state)
A : if(in == 1'b0)
state <= A;
else
state <= B;
B : if(in == 1'b0)
state <= C;
else
state <= B;
C : if(in == 1'b0)
state <= A;
else
state <= D;
D : if(in == 1'b0)
state <= C;
else
state <= B;
default : state <= A;
endcase
end
always @(posedge clk ) begin // 第二段描述状态和输入对输出的影响
if(reset == 1'b1)
out <= 1'b0;
else if(state == C & in==1)
out <= 1'b1;
else
out <= 1'b0;
end
endmodule
Fsm onehot
module top_module(
input in,
input [9:0] state,
output [9:0] next_state,
output out1,
output out2);
assign next_state[0] = ~in & (state[0] | state[1] | state[2] | state[3] | state[4] | state[7] | state[8] | state[9]);
assign next_state[1] = in & (state[0] | state[8] | state[9]);
assign next_state[2] = in & state[1];
assign next_state[3] = in & state[2];
assign next_state[4] = in & state[3];
assign next_state[5] = in & state[4];
assign next_state[6] = in & state[5];
assign next_state[7] = in & (state[6] | state[7]);
assign next_state[8] = ~in & state[5];
assign next_state[9] = ~in & state[6];
assign out1 = state[8] | state[9];
assign out2 = state[7] | state[9];
endmodule
Fsm ps2
一开始,看不懂想说啥,hint给出了状态机转移图:我又行了 dog.jpg
这是一个三段式状态机的代码编写,其实说实话,为了简洁性确实可以将第一段always和第二段always写成一段。
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output done); //
parameter byte1=4'b0001;
parameter byte2=4'b0010;
parameter byte3=4'b0100;
parameter DONEE=4'b1000;
reg [3:0] current_state;
reg [3:0] next_state;
always @(posedge clk)begin
if(reset==1)
current_state <= byte1;
else
current_state <= next_state;
end// State transition logic (combinational)
always @(*)begin//这段代码有问题,应该加上reset的判断的,优化后的代码请看下面一题的解答
case(current_state)
byte1 : if(in[3]==0)
next_state<=byte1;
else
next_state<=byte2;
byte2 : next_state<=byte3;
byte3 : next_state<=DONEE;
DONEE : if(in[3]==0)
next_state<=byte1;
else
next_state<=byte2;
endcase
end// State flip-flops (sequential)
always @(posedge clk)begin
if(reset==1)
done<=0;
else
begin
if(next_state==DONEE)
done<=1;
else
done<=0;
end
end// Output logic
endmodule
Fsm ps2data
其实这就是一个在原有的 Fsm ps2 基础上增加了一个输出,现在问题是这个输出如何表达。to be honest,我没想到答案,因为这是我第一次在状态机中遇见多输出的情况,没想到可以通过增加always模块来增加输出。
说实话,这个题目描述的就晕晕的,虽然写对了,但不知道他的目的是啥,唯一能学到的是状态机的多输出。
module top_module(
input clk,
input [7:0] in,
input reset, // Synchronous reset
output [23:0] out_bytes,
output done);
parameter byte1=4'b0001;
parameter byte2=4'b0010;
parameter byte3=4'b0100;
parameter DONEE=4'b1000;
reg [3:0] current_state;
reg [3:0] next_state;
// State transition logic (combinational)
always @(posedge clk)begin
if(reset==1)
current_state <= byte1;
else
current_state <= next_state;
end
// State flip-flops (sequential)
always @(*)begin
if(reset==1'b1)
next_state <= byte1;
else
begin
case(current_state)
byte1 : if(in[3]==0)
next_state<=byte1;
else
next_state<=byte2;
byte2 : next_state<=byte3;
byte3 : next_state<=DONEE;
DONEE : if(in[3]==0)
next_state<=byte1;
else
next_state<=byte2;
default: next_state<=byte1;
endcase
end
end
//额外增加输出逻辑
always @(posedge clk)begin
if(reset==1'b1)
out_bytes [23:0] <= 24'b0;
else
begin
case(current_state)
byte1 : out_bytes [23:16] <= in [7:0];
byte2 : out_bytes [15:8] <= in [7:0];
byte3 : out_bytes [7:0] <= in [7:0];
DONEE : out_bytes [23:16] <= in [7:0];
endcase
end
end
// Output logic
always @(posedge clk)begin
if(reset==1)
done<=0;
else
begin
if(next_state==DONEE)
done<=1;
else
done<=0;
end
end
endmodule
Fsm serial
题目分析:
这道题是想要让我们描述如图所示的串行通信协议,给定一个比特流,我们所描述的状态机需要正确的识别何时正确的接收字节,其中需要识别包括 一位起始位,8位有效数据,一位停止位 共10位,当正确检验后,done拉高一个时钟周期。如果接收最后一个停止位时失败则需要等待 in拉高后在重新识别,并且不接收先前的数据。
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output done
);
//-----------parameter list-----------------//
localparam IDLE = 12'b000_000_000_001;
localparam START = 12'b000_000_000_010;
localparam BYTE1 = 12'b000_000_000_100;
localparam BYTE2 = 12'b000_000_001_000;
localparam BYTE3 = 12'b000_000_010_000;
localparam BYTE4 = 12'b000_000_100_000;
localparam BYTE5 = 12'b000_001_000_000;
localparam BYTE6 = 12'b000_010_000_000;
localparam BYTE7 = 12'b000_100_000_000;
localparam BYTE8 = 12'b001_000_000_000;
localparam STOP = 12'b010_000_000_000;
localparam WAIT = 12'b100_000_000_000;
//-------------reg list--------------------//
reg [11:0] c_state;
reg [11:0] n_state;
//State transition logic (combinational)
always @(*) begin
case(c_state)
IDLE : n_state = (~in) ? START : IDLE; //detect the start bit
START : n_state = BYTE1; //denote that you find the start bit, begin to receive data
BYTE1 : n_state = BYTE2; //denote that receive the first bit
BYTE2 : n_state = BYTE3; //...
BYTE3 : n_state = BYTE4;
BYTE4 : n_state = BYTE5;
BYTE5 : n_state = BYTE6;
BYTE6 : n_state = BYTE7;
BYTE7 : n_state = BYTE8;
BYTE8 : n_state = (in) ? STOP : WAIT ; //detect the stop bit, if not find, jump to WAIT state
STOP : n_state = (in) ? IDLE : START; //mean that you find the stop bit. if the next bit of input signal is "1"
//jump to IDLE state. otherwise, FSM can skip IDLE state and jump to START state.
WAIT : n_state = (in) ? IDLE : WAIT; //In WAIT state, the input signal is "1" which mean that FSM can restart
default : n_state = IDLE;
endcase
end
//State Flip-Flops with synchronous reset
always @(posedge clk) begin
if (reset == 1'b1)
c_state <= IDLE;
else
c_state <= n_state;
end
//Moore Finite State Machine Output logic
assign done = (c_state == STOP);
endmodule
Fsm serialdata
我已经明白它的意思了,还是一个8位的串行通讯接受器,只不过增加了输出功能。
module top_module(
input clk,
input in,
input reset, // Synchronous reset
output [7:0] out_byte,
output done
);
//-----------parameter list-----------------//
localparam IDLE = 12'b000_000_000_001;
localparam START = 12'b000_000_000_010;
localparam BYTE1 = 12'b000_000_000_100;
localparam BYTE2 = 12'b000_000_001_000;
localparam BYTE3 = 12'b000_000_010_000;
localparam BYTE4 = 12'b000_000_100_000;
localparam BYTE5 = 12'b000_001_000_000;
localparam BYTE6 = 12'b000_010_000_000;
localparam BYTE7 = 12'b000_100_000_000;
localparam BYTE8 = 12'b001_000_000_000;
localparam STOP = 12'b010_000_000_000;
localparam WAIT = 12'b100_000_000_000;
//-------------reg list--------------------//
reg [11:0] c_state;
reg [11:0] n_state;
reg [9:0] out_byte_reg; //save all bits of input signal
//State transition logic (combinational)
always @(*) begin
case(c_state)
IDLE : n_state = (~in) ? START : IDLE; //detect the start bit
START : n_state = BYTE1; //denote that you find the start bit, begin to receive data
BYTE1 : n_state = BYTE2; //denote that receive the first bit
BYTE2 : n_state = BYTE3; //...
BYTE3 : n_state = BYTE4;
BYTE4 : n_state = BYTE5;
BYTE5 : n_state = BYTE6;
BYTE6 : n_state = BYTE7;
BYTE7 : n_state = BYTE8;
BYTE8 : n_state = (in) ? STOP : WAIT ; //detect the stop bit, if not find, jump to WAIT state
STOP : n_state = (in) ? IDLE : START; //mean that you find the stop bit. if the next bit of input signal is "1",
//jump to IDLE state. otherwise, FSM can skip IDLE state and jump to START state.
WAIT : n_state = (in) ? IDLE : WAIT; //In WAIT state, the input signal is "1" which mean that FSM can restart
default : n_state = IDLE;
endcase
end
//State Flip-Flops with synchronous reset
always @(posedge clk) begin
if (reset == 1'b1)
c_state <= IDLE;
else
c_state <= n_state;
end
//Moore Finite State Machine Output logic
assign done = (c_state == STOP);
assign out_byte = out_byte_reg[8:1]; //because out_byte always output when FSM is in the STOP state (or done is "1"
//so this equation always will take the right data from input port
always @(posedge clk) begin
if(reset == 1'b1)
out_byte_reg <= 8'd0;
else
out_byte_reg <= {in,out_byte_reg[9:1]}; //我一开始错在往特定寄存器写数据,而不是通过移位来存储数据
end
//可以往特定寄存器写入数据,只不过需要判断状态,忘了之前的错误写法是什么样了
/* 往寄存器的特定某位写入数据
reg [7:0] out_reg;
always@(posedge clk) begin
if(reset) begin
out_reg <= 8'b0;
end
else begin
case(next)
S0: out_reg[0] <= in;
S1: out_reg[1] <= in;
S2: out_reg[2] <= in;
S3: out_reg[3] <= in;
S4: out_reg[4] <= in;
S5: out_reg[5] <= in;
S6: out_reg[6] <= in;
S7: out_reg[7] <= in;
PARITY: out_reg <= out_reg;
STOP: out_reg <= out_reg;
default: out_reg <= 8'b0;
endcase
end
end
*/
endmodule
双脉冲发波程序
//鏃堕挓棰戠巼 100MHz 鏃堕挓鍛ㄦ湡1e-8s
//浠庤Е鎽稿睆鍒癋PGA 32us
module double_pulse(
input clk,//
input reset,
input [31:0] T_charge,
input [31:0] T_charge2,
input [31:0] T_delay,
input [31:0] T1,
input [31:0] T2,
input [31:0] T3,
input [31:0] Td,
input enable,
output reg Sp,
output reg Sn);
//灏嗘椂闂村懡浠よ浆鎹㈡垚鏃堕挓鍛ㄦ湡(璁℃暟鍣?)涓暟
//T_charge = T_charge //* 100e6;
//T_charge2 = T_charge2 //* 100e6;
//T_delay = T_delay //* 100e6;
//T1 = T1 //* 100e6;
//T2 = T2 //* 100e6;
//T3 = T3 //* 100e6;
//Td = Td //* 100e6;
//鐘舵?佹満
//瀹氫箟鐘舵??
parameter state1 = 12'b0000_0000_0001;
parameter state2 = 12'b0000_0000_0010;
parameter state3 = 12'b0000_0000_0100;
parameter state4 = 12'b0000_0000_1000;
parameter state5 = 12'b0000_0001_0000;
parameter state6 = 12'b0000_0010_0000;
parameter state7 = 12'b0000_0100_0000;
parameter state8 = 12'b0000_1000_0000;
parameter state9 = 12'b0001_0000_0000;
parameter state10 = 12'b0010_0000_0000;
parameter state11 = 12'b0100_0000_0000;
parameter IDLE = 12'b1000_0000_0000;
reg [11:0] c_state;
reg [11:0] n_state;
reg [63:0] counter;
initial counter = 63'd0;
always @(posedge clk)begin
if(reset==1)
c_state <= IDLE;
else
c_state <= n_state;
end// State transition logic (combinational)
//鐘舵?佽浆绉婚?昏緫
always @(*) begin // 绗竴娈靛彧鎻忚堪杈撳叆鍜岀姸鎬佷箣闂寸殑鍏崇郴
if(reset == 1'b1)
n_state <= IDLE;
else case(c_state)
IDLE: if(enable == 1)
n_state <= state1;
state1: if(counter == T_charge)
n_state <= state2;
state2: if(counter == 2*T_charge)
n_state <= state3;
state3: if(counter == (2*T_charge + T_charge2))
n_state <= state4;
state4: if(counter == (2*T_charge + T_charge2 + T_delay))
n_state <= state5;
state5: if(counter == (2*T_charge + T_charge2 + T_delay + T1))
n_state <= state6;
state6: if(counter == (2*T_charge + T_charge2 + T_delay + T1 + Td))
n_state <= state7;
state7: if(counter == (2*T_charge + T_charge2 + T_delay + T1 + Td + T2))
n_state <= state8;
state8: if(counter == (2*T_charge + T_charge2 + T_delay + T1 + 2*Td + T2))
n_state <= state9;
state9: if(counter == (2*T_charge + T_charge2 + T_delay + T1 + 2*Td + T2 + T3))
n_state <= state10;
state10:if(counter == (2*T_charge + T_charge2 + T_delay + T1 + 3*Td + T2 + T3))
n_state <= state11;
state11:if(enable == 1'b0)
n_state <= IDLE;
default:n_state <= IDLE;
endcase
end
always @(posedge clk ) begin // 绗簩娈垫弿杩扮姸鎬佸拰杈撳叆瀵硅緭鍑虹殑褰卞搷 Sp娉㈠舰
if(reset == 1'b1)
begin
Sp <= 1'b0;
end
else if(n_state == state1)
Sp <= 1'b1;
else if(n_state == state2)
Sp <= 1'b0;
else if(n_state == state3)
Sp <= 1'b1;
else if(n_state == state4)
Sp <= 1'b0;
else if(n_state == state5)
Sp <= 1'b1;
else if(n_state == state6)
Sp <= 1'b0;
else if(n_state == state7)
Sp <= 1'b0;
else if(n_state == state8)
Sp <= 1'b0;
else if(n_state == state9)
Sp <= 1'b1;
else if(n_state == state10)
Sp <= 1'b0;
else if(n_state == state11)
Sp <= 1'b0;
else
Sp <= 1'b0;
end
always @(posedge clk ) begin // 绗簩娈垫弿杩扮姸鎬佸拰杈撳叆瀵硅緭鍑虹殑褰卞搷 Sn娉㈠舰
if(reset == 1'b1)
begin
Sn <= 1'b0;
end
else if(n_state == state1)
Sn <= 1'b0;
else if(n_state == state2)
Sn <= 1'b1;
else if(n_state == state3)
Sn <= 1'b0;
else if(n_state == state4)
Sn <= 1'b0;
else if(n_state == state5)
Sn <= 1'b0;
else if(n_state == state6)
Sn <= 1'b0;
else if(n_state == state7)
Sn <= 1'b1;
else if(n_state == state8)
Sn <= 1'b0;
else if(n_state == state9)
Sn <= 1'b0;
else if(n_state == state10)
Sn <= 1'b0;
else if(n_state == state11)
Sn <= 1'b1;
else
Sn <= 1'b0;
end
//璁℃暟鍣?
always @ (posedge clk) begin
if(reset==1|counter==(2*T_charge + T_charge2 + T_delay + T1 + 3*Td + T2 + 100*T3))//
counter <= 0;
else if(c_state == state1||c_state == state2||c_state == state3||c_state == state4||c_state == state5||c_state == state6||c_state == state7||c_state == state8||c_state == state9||c_state == state10||c_state == state11)
counter <= counter + 1;
end
endmodule
`timescale 1ns/1ns
module td_double_p();
//****************** Parameter and Internal Signal *******************//
//********************************************************************//
//wire define
wire Sp ;
wire Sn ;
//reg define
reg sys_clk;
reg reset;
reg enable;
reg [31:0] T_charge;
reg [31:0] T_charge2;
reg [31:0] T_delay;
reg [31:0] T1;
reg [31:0] T2;
reg [31:0] T3;
reg [31:0] Td;
//********************************************************************//
//***************************** Main Code ****************************//
//********************************************************************//
//鍒濆鍖栫郴缁熸椂閽?
initial begin
sys_clk = 1'b1;
enable = 1'b1;
reset = 1'b0;
T_charge = 32'd20;
T_charge2 = 32'd20;
T_delay = 32'd20;
T1 = 32'd20;
T2 = 32'd20;
T3 = 32'd20;
Td = 32'd20;
end
//sys_clk:妯℃嫙绯荤粺鏃堕挓锛屾瘡 5ns 鐢靛钩缈昏浆涓?娆★紝鍛ㄦ湡涓? 10ns锛岄鐜囦负 100MHz
always #5 sys_clk = ~sys_clk;
//********************************************************************//
//**************************** Instantiate ***************************//
//********************************************************************//
//------------- led_inst -------------
double_pulse double_p_inst
(
.clk (sys_clk ),
.reset(reset),
.T_charge(T_charge),
.T_charge2(T_charge2),
.T_delay(T_delay),
.T1(T1),
.T2(T2),
.T3(T3),
.Td(Td),
.enable(enable),
.Sp(Sp),
.Sn(Sn)
);
endmodule