0

我想做一个简单的项目,在我的 Altera DE1-SOC 的 SDRAM 中加载 10 个数字,准备作为我正在创建的逻辑单元的输入,

逻辑单元只做一个简单的算术“Y =(X+1)*(X-1),X是输入,Y是输出”。它将从SDRAM中(一个接一个)选择值,计算并在另一个 SDRAM 排列中吐出结果。

然后 SDRAM 应该存储这些数据,例如,我希望将这些数据从 DE1-SOC 中取出到 PC。

到目前为止,我已经完成了这段代码,(以防万一需要检查):

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

这是我“模拟”为输入数据 RAM 的内存:

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

这用于输出数据:

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

和测试台:

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

所以,基本上现在我想用“模拟”RAM 代替真正的 SDRAM,我不知道最实用的方法是什么。

我应该使用 QSYS、NIOS-II,还是仅通过学习 Megawizard IP 库并生成 UniPHY 的变体。我只是在学习使用 FPGA,所以我在这部分有点困惑。我想下载正确的手册和教程以详细了解这一点,但我希望你们能指导我。

PD:我的目标是将我的逻辑单元与“模拟内存”“隔离”,因为我猜如果我像我一样编程,它会消耗逻辑资源,我的主要目标是计算面积、能量和速度只消耗我的逻辑,没有记忆负担。

谢谢。

4

3 回答 3

1

您的关键字(QSYS、megawizard、uniphy)表示 Altera。如果你只是要模拟 SDRAM,你应该没问题。有时,第一次在真正的芯片中调出该接口会让人毛骨悚然。

如果你只是在做模拟,我会使用 QSYS 来生成 SDRAM 控制器模块。如果你可以做 DDR3,那就有能力生成一个示例设计。如果这样做,您将能够看到 DDR3 的接口是如何工作的。事实上它应该已经走了。

作为一个仅供参考,读取会有更多的延迟,因此您需要能够等待响应,或者您需要一个管道架构,您可以在其中同时进行多个读取。

于 2016-09-23T18:45:42.530 回答
1

“FPGA 现在是什么?” 教程提供了一些关于 SDRAM 仿真的建议(对于 Xilinx 平台,这显然与您的特定情况不匹配)。基本上,它归结为找到具有可用 Verilog/VHDL 模型的 SDRAM 供应商,并将其插入仿真测试台。(请注意,这些模型将无法合成。)

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

于 2016-09-25T17:51:56.230 回答
0

Altera 有一个将 SDRAM 连接到 DE1-SoC 板上的 Nios II 系统(使用 Qsys)的教程。

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

如果您正在实现自己的控制器(或使用仅硬件 IP 核),本教程还包含 SDRAM 的时序信息。

于 2016-09-28T14:04:46.460 回答