Verilog 入门(九)(建模实例)

建模的不同方式

分别使用数据流方式、行为方式和结构方式对下图所示的电路进行建模:

在这里插入图片描述
数据流方式:使用连续赋值语句对电路建模

module Save_Mult_Df(A, C, ClkB, Z);
  input[0:7] A;
  input[0:3] C;
  input ClkB;
  output[0:11] Z;
  wire S1;

  assign Z = S1 * C;
  assign S1 = ClkB ? A : S1;
endmodule

行为方式:使用带有顺序程序块的 always 语句,将电路建模为顺序程序描述。

module Save_Mult_Df(A, C, ClkB, Z);
  input[0:7] A;
  input[0:3] C;
  input ClkB;
  output[0:11] Z;
  reg[0:11] Z;

  always@(A or C or ClkB) begin:SEQ
    reg[0:7] S1;
    if(ClkB)
      S1 = A;
    Z = S1 * C;
  end
endmodule

结构方式:是假定已存在 8 位寄存器和 8 位乘法器,将电路建模为线网表。

module Save_Mult_Df(A, C, ClkB, Z);
  input[0:7] A;
  input[0:3] C;
  input ClkB;
  output[0:11] Z;
  wire[0:7] S1, S3;
  wire[0:15] S2;

  Reg8 R1(.Din(A), .Clk(ClkB), .Dout(S1));
  Mult8 M1(.A(S1), .B({
    
    4'b0000, C}), .Z(Z));
endmodule

条件操作建模

在特定条件下发生的操作可以使用带有条件操作符的连续赋值语句,或在 always 语句中用 if 语句或 case 语句建模。如下面描述的一个算术逻辑电路:

module Simple_ALU(A, B, C, PM, ALU);
  input[0:3] A, B, C;
  input PM;
  output[0:3] ALU;

  assign ALU = PM ? A + B : A - B;
endmodule

多路选择开关也能够使用 always 语句建模。首先确定选线的值,然后,case 语句根据这个值选择相应的输入赋值到输出。

`timescale 1ns/1ns
module Multiplexer(Sel, A, B, C, D, Mux_Out);
  input[0:1] Sel;
  input A, B, C, D;
  output Mux_Out;
  reg Mux_Out;
  reg Temp;
  parameter MUX_DELAY = 15;

  always@(Sel or A or B or C or D)
    begin:P1
      case(Sel)
        0: Temp = A;
        1: Temp = B;
        2: Temp = C;
        3: Temp = D;
      endcase
      Mux_Out = #MUX_DELAY Temp
    end
endmodule

通用移位寄存器

通用串行输入、串行输出移位寄存器能够使用 always 语句块内的 for 循环语句建模。寄存器的数量被定义为参数,这样通用移位寄存器的数量在其他设计中被引用时,可以修改。

module Shift_Reg(D, Clock, Z);
  input D, Clock;
  output Z;
  parameter NUM_REG = 6;
  reg[1:NUM_REG] Q;
  integer P;

  always@(negedge Clock) begin
    // 寄存器右移一位
    for(P=1; P<NUM_REG; P=P+1)
      Q[P+1] = Q[P]
    // 加载串行数据
    Q[1] = D;
  end

  // 从最右端寄存器获取输出;
  assign Z = Q[NUM_REG];
endmodule

状态机建模

状态机通常可使用带有 always 语句的 case 语句建模。状态信息存储在寄存器中。case 语句的多个分支包含每个状态的行为。下面是表示状态机简单乘法算法的实例:

在这里插入图片描述

module Multiply(Mplr, Mcnd, Clock, Reset, Done, Acc);
  input[0:15] Mplr, Mcnd;
  input Clock, Reset;
  output Done;
  reg Done;
  output[31:0] Acc;
  reg[31:0] Acc;
  parameter INIT = 0, ADD = 1, SHIFT = 2;
  reg[0:1] Mpy_State;
  reg[31:0] Mcnd_Temp;

  initial Mpy_State = INIT;

  always@(negedge Clock) begin:PROCESS
    integer Count;
    case(Mpy_State)
      INIT:
        if(Reset)
          Mpy_State = INIT;
        else
          begin
            Acc = 0;
            Count = 0;
            Mpy_State = ADD;
            Done = 0;
            Mcnd_Temp[15:0] = Mcnd;
            Mcnd_Temp[31:16] = 1'd0;
          end
      ADD:
        begin
          if(Mplr[Count])
            Acc = Acc + Mcnd_Temp
            Mpy_State = SHIFT;
          end
      SHIFT:
        begin
          Mcnd_Temp = {
    
    Mcnd_Temp[30:0], 1'b0};
          Count = Count + 1;
          if(Count == 16)
            begin
              Mpy_State = INIT;
              Done = 1;
            end
          else
            Mpy_State = ADD;
        end
    endcase
  end
endmodule

Moore 有限状态机建模

Moore 有限状态机(FSM)的输出只依赖于状态而不依赖其输入。这种类型有限状态机的行为能够通过使用带有在状态值上转换的 case 语句的 always 语句建模。

在这里插入图片描述

module Moore_FSM(A, Clock, Z);
  input A, Clock;
  output Z;
  reg Z;

  parameter STO = 0, ST1 = 1, ST2 = 2, ST3 = 3;
  reg[0:1] Moore_State;

  always@(negedge Clock)
    case(Moore_State)
      ST0: begin
        Z = 1;
        if(A)
          Moore_State = ST2;
      end

      ST1: begin
        Z = 0;
        if(A)
          Moore_State = ST3;
      end

      ST2: begin
        Z = 0;
        if(~A)
          Moore_State = ST1;
        else
          Moore_State = ST3;
      end

      ST3: begin
        Z = 1;
        if(A)
          Moore_State = ST0;
      end
    endcase
endmodule

Mealy 型有限状态机建模

在 Mealy 型有限状态机中,输出不仅依赖机器的状态而且依赖于它的输入。

在这里插入图片描述

module Mealy_FSM(A, Clock, Z);
  input A, Clock;
  output Z;
  reg Z;

  parameter STO = 0, ST1 = 1, ST2 = 2, ST3 = 3;
  reg[1:2] P_State, N_State;

  always@(negedge Clock)
    P_State = N_State;

  always@(P_State or A) begin:COMB_PART
    case(P_State)
      ST0:
        if(A) begin
          Z = 1;
          N_State = ST3;
        end
        else
          Z = 0;

      ST1:
        if(A) begin
          Z = 0;
          N_State = ST0;
        end
        else
          Z = 1;

      ST2:
        if(~A)
          Z = 0;
        else begin
          Z = 1;
          N_State = ST1;
        end

      ST3:
        begin
          Z = 0;
          if(~A)
            N_State = ST2;
          else
            N_State = ST1;
        end
    endcase
  end
endmodule

猜你喜欢

转载自blog.csdn.net/myDarling_/article/details/134764849