在 Verilog 行为建模中复制寄存器值

Copying register value in Verilog behavioral modelling

我正在使用行为建模方法在 Verilog 中设计加密模块,但我无法将寄存器值传递到 Data_out 端口。我在 Data_out 端口复制寄存器 p 值时犯了一点错误。还附有测试平台。模块的预期输出应该是 Data_out = (Data_in + Key) MOD 26. 但由于系统问题,我们不能使用 % 运算符。 你的回答对我很有价值。

module encription(Start,Clk,Reset,Data_In, Key,Data_out,Done);

parameter M='d26;
parameter S0=0, S1=1, S2= 2;
input Clk,Reset,Start;
input [4:0] Data_In,Key;
output reg [4:0] Data_out;
output reg Done;
 reg [1:0] state;
 reg [4:0] p,q,r,s;
 
 always @ (posedge Clk)
 begin
 r <= Data_In;
 s <= Key;
 end
 
 
 always @ (posedge Clk )
    begin
      if(Reset=='b0)
        begin
            Done <= 1'b0;
            p <= M;
        end
        else if (Reset == 'b1)
        case (state)
         S0: 
         if (Start) begin
         q <= r + s;
         
         state <= S1;
         end
         S1: 
         if (p >= q) begin
         p <= p - q;
         state <= S2;
         end
         S2:
         begin
               Data_out <= p;
               Done <= 1'b1;
               Done <= 1'b0;
               end
               default:
               state <= S0;
endcase

end
endmodule



module Encryption_tb();

reg Clk,Reset,Start;
reg [4:0] Data_In,Key;
wire [4:0] Data_out;
wire [4:0] q;
wire Done;

  encription DUT(Start,Clk,Reset,Data_In, Key,Data_out,Done);
initial
    begin
    Clk = 0;
    forever #5 Clk=~Clk;
    end
    
    initial
    begin
        #10 Start = 'b1;  Data_In = 'b000111; Key = 'b01110;
    #10 Start = 'b1;  Data_In = 'b000101; Key = 'b01100;
    #10 Start = 'b1;  Data_In = 'b000001; Key = 'b00110;
    #10 Reset = 'b1; Start = 'b1;
    //#10 Reset = 'b0;
    #10 Start = 'b1;  Data_In = 'b000111; Key = 'b01110;
    #10 Start = 'b1;  Data_In = 'b000101; Key = 'b01100;
    #10 Start = 'b1;  Data_In = 'b000001; Key = 'b00110;
    #10 $finish;
    end
endmodule

我看到了几个问题。

  1. 在你的状态机中退出 S1 的唯一方法是 if "if (p >= q)"。如果 p 已经小于 Q,你将永远停留在那个状态。

  2. 在您的测试平台中,您为您的状态提供了两次启动之间的时间 机器到 运行.

几点建议: 更好的缩进可以更容易地查看代码块中的内容:例如:

        S1: 
          if (p >= q) begin
             p <= p - q;
             state <= S2;
          end

在您的测试台中,不要使用#10 来定义刺激序列,而是使用@(posedge Clk),这样,如果您的时钟频率发生变化或在 TB 中使用了其他长度延迟,事情仍然会发生变化跟上时钟。 使用@(Done)等待结果。

我也很好奇,你用的什么综合工具不支持%?

这不需要状态机,只需要一些触发器。
右图:

module encription(Start,Clk,Reset,Data_In, Key,Data_out,Done);

parameter M='d26;
parameter S0=0, S1=1, S2= 2;
input Clk,Reset,Start;
input [4:0] Data_In,Key;
output reg [4:0] Data_out;
output reg Done;
  
  reg [6:0] sum;

assign sum = Data_In + Key;
 
 always @ (posedge Clk )
    begin
      if(Reset=='b1)
        begin
            Data_out <= 0;
            Done <= 0;         
        end
        else
          begin
          if(sum < M)
            Data_out <= sum;
            else
              if(sum < 2*M)
                Data_out <= sum - M;
               else
                 Data_out <= sum - 2*M ;
            
            Done <= Start;
          end
    end

endmodule    

具有有意义向量的测试平台:

    module Encryption_tb();

reg Clk,Reset,Start;
reg [4:0] Data_In,Key;
wire [4:0] Data_out;
wire [4:0] q;
wire Done;

  encription DUT(Start,Clk,Reset,Data_In, Key,Data_out,Done);
  
  
initial
    begin 
    Clk = 0;
    forever #5 Clk=~Clk;
    end
    
    initial
    begin :initial_block
      
      $monitor("Data_In = %d,Key = %d, Data_out = %d",Data_In,Key,Data_out);
      
    Reset = 1;
    #20 Reset = 0;
      
    #10;
      
    #1;
    Start = 1;
      for(int i = 0; i < 30; i++)
        begin
          @ (posedge Clk);
          #1;
          Key = i;
          Data_In = i;
        end

    #10 $finish;
    end :initial_block
  
  initial
    begin
      $dumpfile("dump.vcd");
      $dumpvars;
    end
  
endmodule    

一些输出(请注意,由于触发器,答案延迟了 1 个时钟)

Data_In =  0,Key =  0, Data_out =  0
Data_In =  1,Key =  1, Data_out =  0
Data_In =  1,Key =  1, Data_out =  2
Data_In =  2,Key =  2, Data_out =  2
Data_In =  2,Key =  2, Data_out =  4
Data_In =  3,Key =  3, Data_out =  4
Data_In =  3,Key =  3, Data_out =  6
Data_In =  4,Key =  4, Data_out =  6
Data_In =  4,Key =  4, Data_out =  8
Data_In =  5,Key =  5, Data_out =  8
Data_In =  5,Key =  5, Data_out = 10
Data_In =  6,Key =  6, Data_out = 10
Data_In =  6,Key =  6, Data_out = 12
Data_In =  7,Key =  7, Data_out = 12
Data_In =  7,Key =  7, Data_out = 14
Data_In =  8,Key =  8, Data_out = 14
Data_In =  8,Key =  8, Data_out = 16
Data_In =  9,Key =  9, Data_out = 16
Data_In =  9,Key =  9, Data_out = 18
Data_In = 10,Key = 10, Data_out = 18
Data_In = 10,Key = 10, Data_out = 20
Data_In = 11,Key = 11, Data_out = 20
Data_In = 11,Key = 11, Data_out = 22
Data_In = 12,Key = 12, Data_out = 22
Data_In = 12,Key = 12, Data_out = 24
Data_In = 13,Key = 13, Data_out = 24
Data_In = 13,Key = 13, Data_out =  0
Data_In = 14,Key = 14, Data_out =  0
Data_In = 14,Key = 14, Data_out =  2
Data_In = 15,Key = 15, Data_out =  2
Data_In = 15,Key = 15, Data_out =  4
Data_In = 16,Key = 16, Data_out =  4
Data_In = 16,Key = 16, Data_out =  6
Data_In = 17,Key = 17, Data_out =  6
Data_In = 17,Key = 17, Data_out =  8
Data_In = 18,Key = 18, Data_out =  8