0
\$\begingroup\$

I am trying to create a register file in Verilog. To do this, I am instantiating multiple instances of a register module I designed in a generate statement. Each module uses a different input and output signal, so I declared an array of buses and indexed them with the genvar in the loop. When trying to synthesize the module, I receive an error informing me of untrimmed latches.

I am using Xilinx ISE

This is the module code:

module RegisterFile(
        input [3:0] RsAddr,
        input [2:0] RsShortAddr,
        input [3:0] RtAddr,
        input [3:0] RdAddr,
        input [2:0] RdShortAddr,
        input [15:0] WriteAddr,
        input [15:0] WriteData,
        input WriteEnable,
        input Reset,
        input Clock,
        output reg [15:0] Rs,
        output reg [15:0] RsShort,
        output reg [15:0] Rt,
        output reg [15:0] Rd,
        output reg [15:0] RdShort
    );

    localparam zero = 16'd0, sp = 16'd1, t0 = 16'd1, t1 = 16'd2, t2 = 16'd3, 
                  ra = 16'd5, s0 = 16'd6, s1 = 16'd7, s2 = 16'd8, rv0 = 16'd9, rv1 = 16'd10, 
                  arg0 = 16'd11, arg1 = 16'd12, at = 16'd13, k0 = 16'd14, k1 = 16'd15; 

    reg [15:0] RegInputMatrix [15:0];
    wire [15:0] RegOutputMatrix [15:0];

    generate
        genvar i;
        for (i = 0; i < 15; i = i + 1) begin : RegisterMatrix
            Register all_Register-5 5(
                .DIN(RegInputMatrix[i]), 
                .WR_EN(WriteEnable & ~Reset), 
                .Reset(Reset), 
                .CLK(Clock), 
                .DOUT(RegOutputMatrix[i])
            );
        end
    endgenerate

    // Write to  a register
    always @(*) begin
        if (Reset)
            RegInputMatrix[WriteAddr] <= 16'b0;
        else
            RegInputMatrix[WriteAddr] <= WriteData;
    end

    // Decode output logic
    always @(posedge Clock or posedge Reset) begin
        if (Reset) begin
            Rs <= 0;
            RsShort <= 0;
            Rt <= 0;
            Rd <= 0;
            RdShort <= 0;
        end
        else begin
            Rs <= RegOutputMatrix[RsAddr];
            RsShort <= RegOutputMatrix[RsShortAddr];
            Rt <= RegOutputMatrix[RtAddr];
            Rd <= RegOutputMatrix[RdAddr];
            RdShort <= RegOutputMatrix[RdShortAddr];
        end
    end

endmodule

I get the following warnings

WARNING:Xst:647 - Input <WriteAddr<15:4>> is never used. This port will be preserved and left unconnected if it belongs to a top-level block or it belongs to a sub-block and the hierarchy of this sub-block is preserved.
WARNING:Xst:653 - Signal <RegOutputMatrix<15>> is used but never assigned. This sourceless signal will be automatically connected to value 0000000000000000.
WARNING:Xst:646 - Signal <RegInputMatrix<15>> is assigned but never used. This unconnected signal will be trimmed during the optimization process.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_0>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_1>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_2>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_3>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_4>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_5>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_6>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_7>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_8>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_9>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_10>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_11>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_12>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_13>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.
WARNING:Xst:737 - Found 16-bit latch for signal <RegInputMatrix_14>. Latches may be generated from incomplete case or if statements. We do not recommend the use of latches in FPGA/CPLD designs, as they may lead to timing problems.

As mentioned above, I believe the Register module is working, but I can provide the hardware description for it if necessary.

\$\endgroup\$
  • \$\begingroup\$ You don't fully assign RegInputMatrix in your always statement, so it needs latches to keep the previous values. \$\endgroup\$ – Eugene Sh. Nov 5 '19 at 18:37
  • \$\begingroup\$ Where is clock man ... \$\endgroup\$ – Mitu Raj Nov 6 '19 at 11:36
  • \$\begingroup\$ @EugeneSh. I understand the issue now. Thanks! \$\endgroup\$ – Nicklas Carpenter Nov 6 '19 at 23:51
  • \$\begingroup\$ @EugeneSh - the question VHDL: Counting Ones in an Array does have a synthesis eligible solution without a clock. The cross over point in complexity for calculating Hamming weight (popcount) combinatorially is at 5 bits. For 8 bits you can do two 4 bit Hamming weights and add the sums together with carry. You can extend that in size with additional summing. \$\endgroup\$ – user8352 Nov 21 '19 at 22:57
2
\$\begingroup\$

Your "Write to a register" is not using a clock:

// Write to  a register
always @(*) begin
    if (Reset)
        RegInputMatrix[WriteAddr] <= 16'b0;
    else
        RegInputMatrix[WriteAddr] <= WriteData;
end

Thus it becomes a latch.

Also that code look suspicious in the reset section. On a reset you only want to clear the register with WriteAddr?

|improve this answer|||||
\$\endgroup\$
  • \$\begingroup\$ That section is intentionally unclocked. The input matrix is the input line to the register; if I clocked input into the matrix, it would take two clock cycles to write to a register. \$\endgroup\$ – Nicklas Carpenter Nov 6 '19 at 23:52
0
\$\begingroup\$

Thank you, everyone, for your input. I was able to get the Register File working. The problem ended up being what was described in the first comment on my post (EugeneSh). I was initializing an array of 16 16-bit buses, but only using one at any given time. I only initialized one of the given buses, so the values of the other buses were undefined. Since Verilog needs each bus to have a definite value, it latched each of the signals, so that each signal would hold its previous value if it was not defined.

My solution to the problem involved nixing the input matrix and using a common input line for each register (16 16-bit buses seemed excessive anyway). Instead, I added an enable line ORed with WriteEnable. This new line is only 16 bits and obtains its value from WriteAddr run through a decoder. The write value is brought to the write input of each register, but each register is only written if WriteEnable is high and the register's corresponding enable bit is high. I testing writing to each register with the WriteEnable bit high and low. It worked as expected. I have included the rewritten module below.

module RegisterFile(
        input [3:0] RsAddr,
        input [2:0] RsShortAddr,
        input [3:0] RtAddr,
        input [3:0] RdAddr,
        input [2:0] RdShortAddr,
        input [3:0] WriteAddr,
        input [15:0] WriteData,
        input WriteEnable,
        input Reset,
        input Clock,
        output reg [15:0] Rs,
        output reg [15:0] RsShort,
        output reg [15:0] Rt,
        output reg [15:0] Rd,
        output reg [15:0] RdShort
    );

    localparam zero = 16'd0, sp = 16'd1, t0 = 16'd1, t1 = 16'd2, t2 = 16'd3, 
                  ra = 16'd5, s0 = 16'd6, s1 = 16'd7, s2 = 16'd8, rv0 = 16'd9, rv1 = 16'd10, 
                  arg0 = 16'd11, arg1 = 16'd12, at = 16'd13, k0 = 16'd14, k1 = 16'd15; 

    wire [15:0] EnableLine;
    wire [15:0] OutputMatrix [15:0];

    // Register Write Address Decoder
    Decoder Addresser (
         .In(WriteAddr), 
         .Reset(Reset), 
         .Out(EnableLine)
    );

    assign OutputMatrix[0] = 0;

    generate
        genvar i;
        for (i = 1; i < 16; i = i + 1) begin : RegisterMatrix
            Register all_Register(
                .DIN(WriteData), 
                .WR_EN(~Reset & WriteEnable & EnableLine[i]), 
                .Reset(Reset), 
                .CLK(Clock), 
                .DOUT(OutputMatrix[i])
            );
        end
    endgenerate

    // Decode output logic
    always @(posedge Clock or posedge Reset) begin
        if (Reset) begin
            Rs <= 0;
            RsShort <= 0;
            Rt <= 0;
            Rd <= 0;
            RdShort <= 0;
        end
        else begin
            Rs <= OutputMatrix[RsAddr];
            RsShort <= OutputMatrix[RsShortAddr];
            Rt <= OutputMatrix[RtAddr];
            Rd <= OutputMatrix[RdAddr];
            RdShort <= OutputMatrix[RdShortAddr];
        end
    end

endmodule

```  
|improve this answer|||||
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.