0

I want to make a simple project on which I load 10 numbers in SDRAM of my Altera DE1-SOC ready to be taken as input for a Logic Unit I am creating,

the logic unit only does a simple arithmetic " Y =(X+1)*(X-1), X is the input and Y is the output ".It will pick the values (one by one) from the SDRAM, calculate and spit out the result in another SDRAM arrangement.

Then the SDRAM should store this data, I wish to take this data out of the DE1-SOC to a PC, for example.

Until now I've done this code, (in case is necessary to check):

module mem_prue1 (rst_n, clk, fin);

input clk, rst_n;
output fin;

wire [6:0] data_X;
reg [6:0] sec_A, sec_B, s_sec_A, s_sec_B;
reg [13:0] rslt_Y, s_rslt_Y;

reg save_sec_A, save_sec_B, save_rslt_Y, set_ram;
reg clear, enable, next_num, no_num, fin, w_mem_out; 

reg [1:0] state, nextstate;
reg [3:0] indx;

parameter S0 = 0; parameter S1 = 1; parameter S2 = 2; parameter S3 = 3;


RAM_IN RAM_IN_inst1 (
.data_X (data_X),
.indx(indx)
);

RAM_OUT RAM_OUT_inst1 (
.s_rslt_Y (s_rslt_Y),
.w_mem_out (w_mem_out), 
.set_ram (set_ram)
);

always @ (posedge clk or negedge rst_n)
begin   

if (~rst_n) 
        begin
            set_ram <= 1;
            indx <= 0;
            no_num <=0;
            enable <= 1;
            s_sec_A <= 0;
            s_sec_B <= 0;
            s_rslt_Y <= 0;
            state <= S0;
        end 
    else if (clear) 
        begin
            enable <= 0;
            state <= nextstate;
            no_num <= 0;
            indx <= 0;
            set_ram <= 1;
            fin <= 1;
        end     
    else
        begin
            set_ram <= 0;
            state <= nextstate;
            if (save_sec_A)
                s_sec_A <= sec_A;
            if (save_sec_B)     
                s_sec_B <= sec_B;
            if (save_rslt_Y)    
                s_rslt_Y <= rslt_Y;
            if (next_num)
                begin
                    if (indx >= 9)
                        begin 
                            indx <= 0;   /// resetea el indice de la memoria
                            no_num <= 1;  // se informa que no hay numeros
                        end
                    else
                        indx <= indx + 4'b0001;
                end 
            end
end

always @ (*)
begin
w_mem_out = 0;
sec_A = 0; sec_B = 0; rslt_Y = 0;
save_sec_A = 0; save_sec_B = 0; 
save_rslt_Y = 0; clear = 0;
next_num = 0;
case (state)

S0: 
        begin
        if (~enable)
            nextstate = S0;
        else 
        begin
            sec_A = data_X + 7'b0000001; 
            save_sec_A = 1;
            nextstate = S1;
        end
        end

S1: begin
        sec_B = data_X - 7'b0000001;
        save_sec_B = 1;
        nextstate = S2;
        end

S2:     begin
        rslt_Y = s_sec_A * s_sec_B;
        save_rslt_Y = 1;
        nextstate = S3;
        end

S3:     begin
        w_mem_out = 1;
        next_num = 1;
        nextstate = S0;
        if (no_num == 1)
            clear = 1;
        end

default:
        nextstate = S0;

    endcase

end

endmodule

This is the memory I "simulated" as a RAM for input data :

module RAM_IN (data_X, indx);


input [0:3] indx;
output [6:0] data_X;


reg [6:0] data_X;
reg [6:0] in_ram [0:9];

always @ (indx)
data_X = in_ram [indx];

initial
begin
$readmemb("C:/altera/15.0/PROYECTOS/mem_prue/in_ram.txt", in_ram);
end

endmodule

and this for output data:

module RAM_OUT (s_rslt_Y, w_mem_out, set_ram);

input [13:0]s_rslt_Y;
input set_ram, w_mem_out;

reg [3:0] addr_out; // tamano de 57600 datos 

reg [13:0] mem_out [0:9];

always @ (w_mem_out or set_ram)
begin

if (set_ram)
addr_out = 0;

else if (w_mem_out == 1) 
    begin
        mem_out [addr_out] = s_rslt_Y;  
        addr_out = addr_out + 4'b0001;
    end
else 
    addr_out = addr_out;

end
endmodule

and The test bench:

module mem_prue1_tb ();

wire fin;
reg clk, rst_n;

mem_prue1 mem_prue1_inst1 (

.clk(clk),
.rst_n (rst_n),
.fin (fin)

);


initial
begin
rst_n <= 1; 
#1 rst_n <= 0;
#2 rst_n <= 1;
clk <= 1;
end 


always
begin
#5 clk = ~clk;
end

//---------------------------
integer out,i;
initial begin
  out=$fopen("C:/altera/15.0/PROYECTOS/mem_prue/mem_out.txt");
end

always@(posedge clk) begin
if(fin==1)        
  for(i=0;i<=9;i=i+1) begin
     $fdisplay(out,"%b",mem_prue1_inst1.RAM_OUT_inst1.mem_out[i]);
    if(i==9)begin
        $stop;
    end
end

end

endmodule

So, basically now I want to substitute that "simulated" RAM for real SDRAM, I don't know what is the most practical way to do it.

Should I use QSYS, NIOS-II, or only by learning the Megawizard IP library and generating a variation of the UniPHY. I'm just learning to use the FPGA, so I'm kinda confused at this part. I want to download the proper manuals and tutorials for learn this in detail but I wish you guys could orient me.

PD: My target would be to "isolate" my logic unit from the "simulated ram" because I'm guessing if I program just like I did, it will consume logic resources and my main goal is to calculate the Area, Energy and Speed consumption of my logic ONLY, without the memory burden.

Thanks.

sujeto1
  • 371
  • 2
  • 4
  • 19
  • 1
    If you only have 10 numbers, any reason why you want to use SDRAM instead on onchip memory (which is easier to use)? – wilcroft Sep 23 '16 at 16:24
  • In fact, this is only a simplification of the full data, original data has thousands of numbers, but for learning purpose I am using here only 10 numbers. – sujeto1 Sep 25 '16 at 06:30
  • @wilcroft do you think for 57.600 32 bits binary numbers is still convenient to use on-chip memory? – sujeto1 Sep 28 '16 at 06:17
  • Maybe? You could certainly give it a try. You'd need 57600*32=1800kbits of memory; the CV FPGA on the DE1-SoC has 3970kbits, so it's use just under half of the memory blocks. – wilcroft Sep 28 '16 at 13:57

3 Answers3

1

Your keywords, (QSYS, megawizard, uniphy) indicate Altera. If you are just going to simulate the SDRAM, you should be okay. Sometimes, bringing up that interface in a real chip gets hairy the first time.

If you are just doing simulation, I would use QSYS to generate the SDRAM controller module. If you can do DDR3, that there is the ability to generate an Example Design. If you do that, you will be able to see how the interface to the DDR3 works. In fact it should be already to go.

As an FYI, there will be more latency on the read though, so you need to be able to either wait for the response, or you need to have a pipeline architecture, where you can have multiple reads in flight simultaneously.

Rich Maes
  • 1,204
  • 1
  • 12
  • 29
  • You mean there will be a latency when loading the data into the SDRAM or, a latency when reading the SDRAM? The first case I don't mind at all, because I only care to know What happen to my logic unit once the SDRAM is already filled and ready to be read. – sujeto1 Sep 25 '16 at 06:35
  • It's when you read the data. The controller sits between you(the host) and the RAM. There are registers in the controller, so it will take a couple extra clocks to get a result. – Rich Maes Sep 25 '16 at 15:41
  • if using SDRAM represent a latency, using on-chip memory would be better for this instance? I need to read and process 57.600 32 bits, binary numbers. Each processing takes a lot of cycles since it's a very complicated arithmetic (unlike the one in example of my post). – sujeto1 Sep 28 '16 at 05:49
  • One more thing, I have a big confusion about what you mention as "if you are just doing simulation", I am trying to design Logic Unit which can perform an specific application, this logic unit should become a real Chip at some point so I think it should be synthesizeable. – sujeto1 Sep 28 '16 at 05:53
  • If the devkit has been around for a while, you will have less issues bringing up the SDRAM for synthesis. My problem usually is that we work with the latest FPGA's that are still under development, and the memory controller IP needs to be tweaked by the vendor. If you are on a DE1, you will be fine. – Rich Maes Sep 28 '16 at 13:18
1

The "FPGAs Now What?" tutorial offers some advice (for a Xilinx platform, which apparently doesn't match your particular case) on SDRAM simulation. Basically, it boils down to finding an SDRAM vendor with an available Verilog/VHDL model, and plugging it in to a simulation testbench. (Note that these models aren't going to be synthesizeable.)

http://www.xess.com/static/media/appnotes/FpgasNowWhatBook.pdf

Joe Oswald
  • 139
  • 1
  • 5
  • Why is not going to be synthesizeable, I wonder what is the correct way to make it synthesizeable? – sujeto1 Sep 28 '16 at 05:51
  • 1
    The obvious reason it is not going to be synthesizeable is because your FPGA almost certainly does not have the internal components to construct an SDRAM of 64MB capacity. The actual reason is that the SDRAM vendor is merely trying to help support simulation not actually provide a functional architecture for the SDRAM function. – Joe Oswald Oct 14 '16 at 15:16
  • 1
    I think I misunderstood your question. The SDRAM model is not meant to be synthesizeable: you implement it by putting an SDRAM chip on the circuit board, not configuring the FPGA. The code your write for your FPGA interface to SDRAM should be synthesizeable. – Joe Oswald Oct 14 '16 at 15:26
0

Altera has a tutorial for connecting the SDRAM to a Nios II system (using Qsys) on the DE1-SoC board.

ftp://ftp.altera.com/up/pub/Altera_Material/16.0/Tutorials/Verilog/DE1-SoC/Using_the_SDRAM.pdf

If you're implementing your own controller (or using a HW only IP Core), the tutorial also has the timing information for the SDRAM as well.

wilcroft
  • 1,580
  • 2
  • 14
  • 20
  • The link you posted only provides a way of making the SDRAM controller using Qsys system, but it does not specifically offer a way of accessing the SDRAM, because reading and writing to the SDRAM (in real life) is difficult. – Andy_A̷n̷d̷y̷ Apr 25 '17 at 04:36
  • @Andy_A̷n̷d̷y̷ The OP specifically asked about possibly using a Nios II CPU, at which point reading and writing memory is trivial once you've implemented the system. – wilcroft Apr 25 '17 at 16:18