Reputation: 411
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.
Upvotes: 0
Views: 1778
Reputation: 1635
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.
Upvotes: 0
Reputation: 139
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
Upvotes: 1
Reputation: 1222
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.
Upvotes: 1