Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

How to declare an array of registers in CyclonI

Hi,

I am writing a design for an university project (for FPGA CYCLON I, using QUARTUS II software).

In this design I want to declare a set (array) of 160 registers of 11bit width each.

How can I declare an array of registers so that the synthesis won't decode it into a ram).

Then according to write or read signals, I have to implement a writing data from data_in bus to the register which index is set on addr bus if write signal is active and to read data from register to data_out bus if read is active.

What I can think of is just declaring each register separately:

reg     register0;
reg     register1;
.................
reg     register159;

And then creating a huge MUX for write/read operation:

case (addr)
    8'h00 :
        if (write)
            register0 <= data_in;
        else
            if (read)
                data_out <= register0;
    ......
    8'd159 :
        ...............
endcase

But it seems to be not the best way to implement this design.

What is the more efficient way? :confused:

Thanks!

7 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You have some options you can set to prevent Quartus from inferring a RAM.

    But why don't you want those registers in RAM?
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Because this design will be finally implemented in ASIC and the demand is to have a block of registers.

    Can you explain where can I find those options?

    And if I declare an array of registers, will the following code be synthesizable?

    if (write)
        register] <= data_in;
    else
        if (read)
            data_out <= register];

    Thanks!!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    There is a setting called "AUTO_RAM_RECOGNITION" that you can set to OFF. I've never tried it on one register but you can set it to architectures at least. Probably should work for one register, if not you can just define a register block.

    --================================================

    -- Set synthesis attribute on architecture

    --================================================

    attribute altera_attribute : string;

    attribute altera_attribute of vhdl_rtl: architecture is "AUTO_RAM_RECOGNITION=OFF";

    Best Regards,

    Ola Bångdahl
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    It's basically synthesizable, assuming suitable register and always block declarations. Generally, these are Verilog syntax rather than Quartus questions.

    According to the Quartus Software Handbook, the below Verilog Syntax suppresses RAM inference for my_ram.

    reg  my_ram /* synthesis syn_ramstyle = "logic" */; 
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    It's basically synthesizable, assuming suitable register and always block declarations. Generally, these are Verilog syntax rather than Quartus questions.

    According to the Quartus Software Handbook, the below Verilog Syntax suppresses RAM inference for my_ram.

    reg  my_ram /* synthesis syn_ramstyle = "logic" */; 

    --- Quote End ---

    --- Quote Start ---

    There is a setting called "AUTO_RAM_RECOGNITION" that you can set to OFF. I've never tried it on one register but you can set it to architectures at least. Probably should work for one register, if not you can just define a register block.

    --================================================

    -- Set synthesis attribute on architecture

    --================================================

    attribute altera_attribute : string;

    attribute altera_attribute of vhdl_rtl: architecture is "AUTO_RAM_RECOGNITION=OFF";

    Best Regards,

    Ola Bångdahl

    --- Quote End ---

    Thank you guys!!!
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Of course design-wide (in Quartus synthesis settings) and architecture-wide settings work as well. But they should use Verilog rather than VHDL syntax in the said case.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Hello!

    This thread is the most relevant to my problem.

    I have a True Dual Port RAM with dual clocks inferred from Quartus II Verilog Template:

    
    // Quartus II Verilog Template
    // True Dual Port RAM with dual clocks
    module true_dual_port_ram_dual_clock# (parameter DATA_WIDTH=8, parameter ADDR_WIDTH=5)
    (
        input  data_a, data_b,
        input  addr_a, addr_b,
        input we_a, we_b, clk_a, clk_b,
        output reg  q_a, q_b
    );
        // Declare the RAM variable
        reg  ram;
        always @ (posedge clk_a)
        begin
            // Port A 
            if (we_a) 
            begin
                ram <= data_a;
                q_a <= data_a;
            end
            else 
            begin
                q_a <= ram;
            end 
        end
        always @ (posedge clk_b)
        begin
            // Port B 
            if (we_b) 
            begin
                ram <= data_b;
                q_b <= data_b;
            end
            else 
            begin
                q_b <= ram;
            end 
        end
    endmodule

    To force Quartus to preserve this RAM as registers I added the following line in *.qsf file:

    set_global_assignment -name AUTO_RAM_RECOGNITION OFF -entity true_dual_port_ram_dual_clock

    I created a simple project to help You reconstruct the problem ( attached http://www.alteraforum.com/forum/attachment.php?attachmentid=9460&stc=1 ) .

    If Quartus compiles this RAM as a RAM, then there are no compilation errors, but if I force Quartus to keep this RAM as registers, then it gives out the following very confusing errors:

    
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10029): Constant driver at TrueDualPortDualClockRAM.v(16)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (10028): Can't resolve multiple constant drivers for net "ram" at TrueDualPortDualClockRAM.v(30)
    Error (12152): Can't elaborate user hierarchy "true_dual_port_ram_dual_clock:inst"
    Error: Result: ERROR: Error(s) found while running an executable. See report file(s) for error message(s). Message log indicates which executable was run last.
    Error: Failed to discover source files from compiler. Check Analysis & Elaboration report.

    What can be done as a workout to prevent Analysis & Synthesis from converting the registers into an altsyncram megafunction?

    As You can see turning off the Auto RAM Replacement logic option for the entity or instance that contains the dual-clock RAM results in strange errors ...

    P.S. All this was done according to the following Altera document:

    http://quartushelp.altera.com/13.1/master.htm#mergedprojects/msgs/msgs/winfer_ram_functionality_change_altsyncram_dual_clock.htm