FPGA:雙口RAM
阿新 • • 發佈:2018-12-28
Xilinx IP核構建雙口RAM
雙口RAM
利用Xilinx提供的IP核構建真雙口RAM,通過狀態機實現從A口寫資料,從B口讀取資料。同樣也可以在B口寫入資料,A口讀取資料。這樣的雙口RAM可以用在異構系統中。
IP核配置
IP核Block Memory Generator配置過程如下:
- Basic 型別選擇Native,True Dual Port RAM;
2.Port A:
3.Port B:
- Other options:
- Summary:
Verilog程式碼
top檔案
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2018/12/18 16:28:04 // Design Name: // Module Name: ram_ftt // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module ram_ftt( input clk, input rst, input ena, input enb, input wea, input [9:0]addr, input [15:0]din, output [15:0]douta, output [15:0]dout ); reg rst_n; // reg ena; // reg enb; // reg wea; reg web; reg [9:0]addra; reg [9:0]addrb; reg [15:0]dina; reg [15:0]dinb; // reg [15:0]douta; reg [15:0]doutb; reg [15:0]din_reg; // reg [31:0]dout; reg [3:0] current_state,next_state; reg write_end; reg read_end; reg [15:0]ram [9:0]; reg [15:0]read_ram [9:0]; // integer i=0; parameter idle=4'b0000, write=4'b0001, read=4'b0010; // assign din=dina; // assign dout=doutb; //第一個always塊,時序邏輯,描述現態轉移到次態 always @ (posedge clk or negedge rst) begin if(!rst) begin current_state<=idle; end else current_state<=next_state; end //第二個always塊,組合邏輯,描述狀態轉移的條件 always @ (current_state or wea) begin case(current_state) idle:begin if(wea) next_state <= write;//狀態轉移 else next_state <= idle; end write:begin if(!wea) next_state <= read;//狀態轉移 else next_state <= write; end read:begin if(addr==10) next_state <= idle;//狀態轉移 else next_state <= read; end default: begin next_state = idle;//狀態轉移 end endcase end //第三個always塊,時序邏輯,描述輸出 always @ (negedge clk or negedge rst) begin if(!rst)begin //addra<=0; //addra<=addr; //dina <= din; // dina<=0; // addrb<=0; end else case(current_state) idle: begin // addra<=0; addra<=0; dina<=0; // addrb<=0; end write: begin //i=i+1; addra<=addr; //addra<=i; dina<=din; end read:begin addrb=addr; end default:begin write_end<=0; read_end<=0; end endcase end blk_mem_gen_0 sim( .clka(clk), .clkb(clk), .ena(ena), .enb(enb), .wea(wea), .web(), .addra(addra), .addrb(addrb), .dina(dina), .dinb(), .douta(douta), .doutb(dout) ); endmodule
testbench
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2018/12/17 15:06:05 // Design Name: // Module Name: sim // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module simu; //module top(clka,clkb,ena,enb,wea,web,addra,addrb,dia,dib,doa,dob); reg clk; reg rst; reg ena; reg enb; reg wea; reg [9:0]addr; reg [15:0]din; wire [15:0]douta; wire [15:0]dout; reg[15:0] ram_a [9:0]; integer i=0; initial $readmemh("F:/date0.txt",ram_a); initial begin clk=0; rst=1; addr=0; ena=0; enb=0; wea=0; din=1; #50 rst= 0; #50 rst=1; ena= 1; wea=1; enb=1; addr=0; end always #10 clk = ~clk; always @(negedge clk or negedge rst) begin if(!rst)begin addr<=1; end else begin addr<=addr+1; if(addr>=10) begin wea<=!wea; addr<=1; end if(wea) din<= ram_a[addr]; end end ram_ftt sim(.clk(clk),.rst(rst),.addr(addr),.din(din),.ena(ena),.enb(enb),.wea(wea),.douta(douta),.dout(dout)); endmodule