Question

I am beginner in verilog and xilinx, and I am writing a quad port ram in verilog,

I want to synthesize my code, but although my code is small, it takes a very long time for synthesize witch I force to stop it and I can not synthesize my code.

I don't know where is the problem and what should I do?here is my own code..

module Dram(CLKM,WEA,WEB,WEC,WED,ENA,ENB,ENC,END,DIA,DIB,DIC,DID,ADDRA,ADDRB,ADDRC,ADDRD,DOA,DOB,DOC,DOD);
input WEA,WEB,WEC,WED,ENA,ENB,ENC,END;
input [17:0]DIA,DIB,DIC,DID;
input [9:0]ADDRA,ADDRB,ADDRC,ADDRD;
input CLKM;
output reg [17:0] DOA,DOB,DOC,DOD;
reg state_reg,state_next;
reg [17:0]ram[1023:0];
always@(posedge CLKM)
begin
    state_reg=state_next;
end///edn for always
always@(negedge  CLKM)
begin
    case(state_reg)
        1'b0:
        begin
            if(ENA)
            begin
                if(WEA)
                    ram[ADDRA]<=DIA;
                DOA<=ram[ADDRA];
            end//////for enA
            if(ENB)
            begin
                if(WEB)
                    ram[ADDRB]<=DIB;
                DOB<=ram[ADDRB];
            end////for enB
            state_next=1'b1;
        end////for 1'b0
        1'b1:
        begin
            if(ENC)
            begin
                if(WEC)
                    ram[ADDRC]<=DIC;
                DOC<=ram[ADDRC];
            end
            if(END)
            begin
                if(WED==1'b1)
                    ram[ADDRD]<=DID;
                DOD<=ram[ADDRD];
            end
            state_next=1'b0;
        end///end for 1'b1
    endcase
end//end for always

endmodule

I thought it is a simple code and doesn't get very time, but now I can not synthesize my code? where is the problem? plz help me!!! thanks

Was it helpful?

Solution

The problem lies in how you access the ram array. You are doing that inside a combinational block. This makes XST to build your RAM using distributed RAM, not block RAM, and builds tons of multiplexers to cover all 1024 possible combinations for ADDRA/ADDRB/ADDRC/ADDRD signals. That is why you are experiencing long synthetizing times.

Rethink your logic so that code like ram[ADDR] <= value or value <= ram[ADDR] is always inside a clock triggered always


After your edited code: I then suggest to separate the quadport RAM logic from the RAM logic itself. You relay on a standard single port RAM module, and then using a FSM, makes it act as if it would have many ports, don't you? Your single port RAM, and the source of your headaches can be described as this:

module spram (input wire clk,
  input wire en,
  input wire we,
  input wire [9:0] addr,
  input wire [17:0] din,
  output reg [17:0] dout
  );

  reg [17:0] ram[0:1023];

  always @(negedge clk) begin
    if (en) begin
      if (we) begin
        ram[addr] <= din;
      end
      dout <= ram[addr];
    end
  end
endmodule

Describing the memory this way will help XST to infere it as a block RAM device, as pointed by the advanced syntesis report:

Synthesizing (advanced) Unit <spram>.
INFO:Xst:3040 - The RAM <Mram_ram> will be implemented as a BLOCK RAM, absorbing the following register(s): <dout>
    -----------------------------------------------------------------------
    | ram_type           | Block                               |          |
    -----------------------------------------------------------------------
    | Port A                                                              |
    |     aspect ratio   | 1024-word x 18-bit                  |          |
    |     mode           | read-first                          |          |
    |     clkA           | connected to signal <clk>           | fall     |
    |     enA            | connected to signal <en>            | high     |
    |     weA            | connected to signal <we>            | high     |
    |     addrA          | connected to signal <addr>          |          |
    |     diA            | connected to signal <din>           |          |
    |     doA            | connected to signal <dout>          |          |
    -----------------------------------------------------------------------
    | optimization       | speed                               |          |
    -----------------------------------------------------------------------
Unit <spram> synthesized (advanced).

Then you can instantiate this RAM into your quadport design and multiplex signals depending on what state you are. Something like this:

module qpram (input wire clk,
  input wire [3:0] en,
  input wire [3:0] we,
  input wire [9:0] addra,
  input wire [9:0] addrb,
  input wire [9:0] addrc,
  input wire [9:0] addrd,
  input wire [17:0] dina,
  input wire [17:0] dinb,
  input wire [17:0] dinc,
  input wire [17:0] dind,
  output reg [17:0] douta,
  output reg [17:0] doutb,
  output reg [17:0] doutc,
  output reg [17:0] doutd
  );

  reg [1:0] port = 2'b00; /* indicates which port is active */
  always @(negedge clk) begin
    port <= port + 1;
  end

  /* instantiate single port RAM */
  reg enable,write;
  reg [17:0] din;
  wire [17:0] dout;
  reg [9:0] addr;
  spram myram (clk,enable,write,addr,din,dout);

  /* multiplexers to assign right inputs to RAM
  depending on which port we are in */
  always @* begin
    case (port)
      2'b00 : begin
                addr = addra;
                write = we[0];
                enable = en[0];
                din = dina;
              end
      2'b01 : begin
                addr = addrb;
                write = we[1];
                enable = en[1];
                din = dinb;
              end
      2'b10 : begin
                addr = addrc;
                write = we[2];
                enable = en[2];
                din = dinc;
              end
      2'b11 : begin
                addr = addrd;
                write = we[3];
                enable = en[3];
                din = dinc;
              end
    endcase
  end

  /* data out is available at the end of each clock cycle */
  always @(negedge clk) begin
    case (port)
      2'b00 : douta <= dout;
      2'b01 : doutb <= dout;
      2'b10 : doutc <= dout;
      2'b11 : doutd <= dout;
    endcase
  end
endmodule

OTHER TIPS

You should probably be triggering your ram reads and writes on an edge of a clock, and not on a level sensitive signal.

Your synthesizer may not be able to understand that state is a pseudo-clock and is trying to infer some weird non-ram behavior, which may be generating a huge logic cone which is difficult to synthesize.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top