Braulio
Braulio

Reputation: 17

SystemVerilog Instantiated Modules Share Inputs When They Shouldn't (Easy Solution)?

I am having a small issue here in when I instantiated my modules. I am using a generate loop to create 100 instances of 2 counters (16 & 32 bit counters). Each counter should have their own independent controls (UPDN & EN), but they share a clock and a reset.

Module Descriptions:

SAT_COUNTER.sv // SIMPLE COUNTER MODULE

TWO_SC.sv // INSTANTIATES TWO SAT_COUNTER MODULES (16 BIT & 32 BIT COUNTERS)

GEN_SC.sv // INSTANTIATES 100 MODULES OF TWO_SC MODULES

tb_GEN_SC.sv // TESTBENCH

I am sure that my problem is in the GEN_SC module where I instantiate all 100..

I appreciate any help! Thank you in advance!

module SAT_COUNTER(
    COUNT,          // SCALABLE COUNT OUTPUT
    CLK,            // CLOCK
    al_RST,         // ACTIVE LOW RESET
    UPDN,           // COUNTER WILL COUNT: UP = 1; DN = 0;
    EN);            // ENABLE

    parameter WIDTH = 8;

    input CLK, al_RST, UPDN, EN;
    output reg [WIDTH-1:0] COUNT;

    ...

endmodule

 //**********************

module TWO_SC(
  COUNT1,       // N-BIT COUNTER OUTPUT
  COUNT2,       // M-BIT COUNTER OUTPUT
  CLK,          // CLOCK
  al_RST,       // ACTIVE-LOW RESET
  UPDN,         // DIR. CONTROL
  EN);          // ENABLE

  parameter WIDTH1 = 16;
  parameter WIDTH2 = 32;

  input CLK, al_RST;
  input [1:0] UPDN, EN;
  output [WIDTH1-1:0] COUNT1;
  output [WIDTH2-1:0] COUNT2;

  SAT_COUNTER   #(WIDTH1) GSC1(.COUNT(COUNT1), .CLK(CLK), .al_RST(al_RST), .UPDN(UPDN[0]), .EN(EN[0]));
  SAT_COUNTER   #(WIDTH2) GSC2(.COUNT(COUNT2), .CLK(CLK), .al_RST(al_RST), .UPDN(UPDN[1]), .EN(EN[1]));

endmodule

//**********************

module GEN_SC(
  COUNT1,       // COUNT1
  COUNT2,       // COUNT2
  CLK,          // CLOCK
  al_RST,       // ACTIVE-LOW RESET
  UPDN,         // DIR. CONTROL
  EN);          // ENABLE

  parameter MOD_COUNT = 100;
  parameter WIDTH1 = 16;
  parameter WIDTH2 = 32;

  input CLK, al_RST;
  input [1:0] UPDN [MOD_COUNT-1:0];
  input [1:0] EN [MOD_COUNT-1:0];
  output [WIDTH1-1:0] COUNT1;
  output [WIDTH2-1:0] COUNT2;

  genvar j;

      generate
        for(j = 0; j < MOD_COUNT; j++) begin: SC
          TWO_SC    #(.WIDTH1(WIDTH1), .WIDTH2(WIDTH2))    TWOCOUNTERS(.COUNT1(COUNT1), .COUNT2(COUNT2), .CLK(CLK), .al_RST(al_RST), .UPDN(UPDN[j]), .EN(EN[j]));
         end
      endgenerate


endmodule

//**********************

module tb_GEN_SC();

parameter MOD_COUNT = 100;
parameter WIDTH1 = 16;
parameter WIDTH2 = 32;

  reg CLK, al_RST;
  reg [1:0] UPDN [MOD_COUNT-1:0];
  reg [1:0] EN [MOD_COUNT-1:0];
  wire [WIDTH1-1:0] COUNT1;
  wire [WIDTH2-1:0] COUNT2;

  GEN_SC    #(.WIDTH1(WIDTH1), .WIDTH2(WIDTH2))    UUT(COUNT1, COUNT2, CLK, al_RST, UPDN, EN);

    initial begin
CLK = 1'b1;
  forever
    #5 CLK = ~CLK;
  end

    initial
    $monitorb("%d  COUNT = %b (%d) | UPDN = %b | EN = %b | COUNT = %b (%d) | UPDN = %b | EN = %b | al_RST = %b | CLK = %b", $time, UUT.SC[87].TWOCOUNTERS.COUNT1, UUT.SC[87].TWOCOUNTERS.COUNT1, UUT.SC[87].TWOCOUNTERS.UPDN[0], UUT.SC[87].TWOCOUNTERS.EN[0], UUT.SC[99].TWOCOUNTERS.COUNT1, UUT.SC[99].TWOCOUNTERS.COUNT1, UUT.SC[99].TWOCOUNTERS.UPDN[0], UUT.SC[99].TWOCOUNTERS.EN[0], al_RST, CLK);

    initial begin
    $vcdpluson;
            UUT.SC[87].TWOCOUNTERS.GSC1.UPDN = 1; UUT.SC[99].TWOCOUNTERS.GSC1.UPDN = 1; EN = 0; al_RST = 1;
    #10                                           UUT.SC[99].TWOCOUNTERS.GSC1.UPDN = 0;         al_RST = 0;           // RESET COUNTER
    #10                                                                                 EN = 1; al_RST = 1;         // ENABLE COUNTER AND COUNT UP (HITS MAX)
    #200    UUT.SC[87].TWOCOUNTERS.GSC1.UPDN = 0; UUT.SC[99].TWOCOUNTERS.GSC1.UPDN = 1; EN = 1;                     // BEGIN TO COUNT DOWN
    #10                                       EN = 0;
    #60                                       EN = 3;
//      #230    UPDN = 1; UPDN = 0;
    #3017                                     al_RST = 0;
    #100                                      al_RST = 1;
    #20 $finish;
    end    

/////////// ERRORS I GET /////////////////

Error-[IBLHS-NT] Illegal behavioral left hand side tb_GEN_SC.sv, 34 Net type cannot be used on the left side of this assignment. The offending expression is : tb_GEN_SC.UUT.SC[87].TWOCOUNTERS.GSC1.UPDN Source info: tb_GEN_SC.UUT.SC[87].TWOCOUNTERS.GSC1.UPDN = 1;

Error-[IBLHS-NT] Illegal behavioral left hand side tb_GEN_SC.sv, 34 Net type cannot be used on the left side of this assignment. The offending expression is : tb_GEN_SC.UUT.SC[99].TWOCOUNTERS.GSC1.UPDN Source info: tb_GEN_SC.UUT.SC[99].TWOCOUNTERS.GSC1.UPDN = 1;

Error-[IUDA] Incompatible dimensions tb_GEN_SC.sv, 34 Incompatible unpacked dimensions in assignment Arrays with incompatible unpacked dimensions cannot be used in assignments, initializations and instantiations.

Error-[ICTA] Incompatible complex type tb_GEN_SC.sv, 34 Incompatible complex type assignment Type of source expression is incompatible with type of target expression. Mismatching types cannot be used in assignments, initializations and instantiations. The type of the target is 'reg[1:0]$[99:0]', while the type of the source is 'int'. Source Expression: 0

Upvotes: 0

Views: 994

Answers (1)

Laleh
Laleh

Reputation: 475

You have just one UPDB and one EN port in port list. So how you wana apply different UPDN and EN to instances?

An idea is to define an array with size of MOD_COUNT so that each element has its own control input. then in genvar loop you can use the index. like this:

input [1:0] UPDN  [MOD_COUNT-1:0];
input [1:0] EN [MOD_COUNT-1:0];

...

generate
    for(j = 0; j < MOD_COUNT; j++) begin: SC

  TWO_SC    #(.WIDTH1(WIDTH1), .WIDTH2(WIDTH2))    TWOCOUNTERS(.COUNT1(COUNT1),
 .COUNT2(COUNT2), .CLK(CLK), .al_RST(al_RST),      .UPDN(UPDN[j]), .EN(EN[j]));

 end
  endgenerate

Upvotes: 1

Related Questions