Search code examples
verilogsystem-verilog

Trouble instantiating and assigning in generate block


I am having trouble understanding how modules inside generate blocks are instantiated.

I am trying to implement a sequence detector that detects 1010. For this, I am trying to use 2 D flip flops. After solving the state table of my sequence, I get:

D1 = (Q2&~X | Q1&~Q2&X), D2 = X, Z = Q1&Q2&~X, where X is my input and Z is the desired output.

Implementing in Verilog, the code I have written so far is:

module d_flipflop(d, clk, q);
  input d, clk;
  output reg q;
    
  always @ (posedge clk)
    q <= d;
endmodule

module seq_detector (clk, inp, outp);
  input [9:0] inp;
  input clk;
  output reg [9:0] outp;
  
  wire d1 = 0;
  wire q1 = inp[9], q2 = inp[8];
  
  generate
    genvar i;
    for (i=9; i>=0; i=i-1) begin
      
      d_flipflop ff2 (.d(inp[i]), .clk(clk), .q(q2) ); // X <=> inp[i]
      assign d1 = (q2 & ~inp[i]) | (q1 & ~q2 & inp[i] );
      d_flipflop ff1 (.d(d1), .clk(clk), .q(q1) );
      
      assign outp[i] = q1 & q2 & ~inp[i]; 
      
    end
  endgenerate
endmodule

module TB_seq_detector();
  reg [9:0] inp, clk;
  wire [9:0] outp;
  
  seq_detector DUT (.clk(clk), .inp(inp), .outp(outp) );
  
  // Generating clock:
  always #10 clk = ~clk;
  // Initializing clk:
  initial clk=0;
      
  // Test case:
  initial begin
    inp = 10'b1000101011;
  end
  
  initial begin
    $display("input: %b", inp[9:0]);
    $display("output: %b", outp[9:0]);
  end
  
  initial #100 $finish;
endmodule

I know that q1 and q2 aren't actually being assigned inp[9] and inp[8] (they are x at time=0). How do I solve this? Should I use non-blocking assignment? Also, as far as I am aware, the generate block runs before simulation time. So my clk is also not affecting anything. How do I solve that?


Solution

  • There are problems with your code that you need to fix.

    If your simulator did not show you a warning similar to the following, then you should run your code on the simulators on EDAPlayground:

    Warning-[PCWM-W] Port connection width mismatch
    "seq_detector DUT( .clk (clk),  .inp (inp),  .outp (outp));"
      The following 10-bit expression is connected to 1-bit port "clk" of module 
      "seq_detector", instance "DUT".
      Expression: clk
    

    The following line declares clk as a 10-bit signal:

      reg [9:0] inp, clk;
    

    You probably want clk to be a 1-bit signal:

    reg clk;
    

    You have multiple drivers for the q1 signal:

    1. The output of the ff1 instance
    2. The continuous assignment: wire q1 = inp[9]

    This causes contention, resulting in x (the unknown value). You must only drive q1 with one source.

    The same is true for q2.