FPGA_WEB_HDLPractice(3)

时间: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:状态机的一段式、二段式、三段式设计各有何优缺点

在状态机设计中,一段式、二段式和三段式是常见的三种设计方法。它们在组织状态之间的转换和对输入的处理方式上有所不同。

  1. 一段式设计:
    在一段式设计中,状态转换和输入处理都集中在一个模块中。整个状态机的逻辑由一个大的代码块实现。一段式设计简单直接,适用于小规模的状态机和简单的应用场景。它的优点是结构简单,易于理解和实现。缺点是当状态机增长复杂时,代码容易变得冗长、难以维护和扩展。

  2. 二段式设计:
    在二段式设计中,状态转换和输入处理分别由两个模块实现。状态转换模块负责管理状态转换逻辑,而输入处理模块负责处理输入信号并触发状态转换。二段式设计将状态转换和输入处理分开,提高了模块化和可复用性。它的优点是结构清晰,易于维护和扩展。缺点是增加了系统的复杂性和开销,需要更多的模块和通信机制。

  3. 三段式设计:
    在三段式设计中,状态转换、输入处理和输出生成分别由三个独立的模块实现。状态转换模块负责管理状态转换逻辑,输入处理模块负责处理输入信号,而输出生成模块负责生成输出信号。三段式设计进一步提高了模块化和可复用性,使系统更加灵活和可扩展。它的优点是模块之间的隔离性强,易于测试和维护。缺点是增加了系统的复杂性和开销,需要更多的模块和通信机制。

选择哪种设计方法取决于具体的应用场景和设计需求。一段式设计适用于简单的状态机和小规模应用,二段式和三段式设计适用于复杂的状态机和大规模应用。在设计过程中,需要综合考虑系统的复杂性、可维护性、扩展性以及开发和测试的成本。

让我们看看野火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]&in;
 
    // 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

在这里插入图片描述

  • 21
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值