
//fsmc read / write ep4ce6 demo
module fsmc(
ab, //address
db, //data
wrn, //wr
rdn, //rd
resetn, //resetn
csn, //cs
ina, //input data a
inb, //input data b
inc, //input data c
ind, //input data d
ine, //input data e
inf, //input data f
ing, //input data g
inh, //input data h
outa, //output data a
outb, //output data a
outc, //output data a
outd, //output data a
oute, //output data a
outf, //output data a
outg, //output data a
outh //output data a
);
input[2:0] ab;
inout[15:0] db;
input wrn;
input rdn;
input resetn;
input csn;
input [15:0] ina;
input [15:0] inb;
input [15:0] inc;
input [15:0] ind;
input [15:0] ine;
input [15:0] inf;
input [15:0] ing;
input [15:0] inh;
output reg [15:0] outa;
output reg [15:0] outb;
output reg [15:0] outc;
output reg [15:0] outd;
output reg [15:0] oute;
output reg [15:0] outf;
output reg [15:0] outg;
output reg [15:0] outh;
wire rd;
wire wr;
reg [15:0] indata;
assign rd = !(csn & rdn); //get rd pulse ____|~~~~|______
assign wr = !(csn & wrn); //get wr pulse ____|~~~~|______
assign db = rd ? indata:16'hzzzz;
//write data, 根据地址线选择八个空间写入,每个空间16位
always @(negedge wr or negedge resetn)
begin
if(!resetn)begin
outa <= 16'h0000;
outb <= 16'h0000;
outc <= 16'h0000;
outd <= 16'h0000;
oute <= 16'h0000;
outf <= 16'h0000;
outg <= 16'h0000;
outh <= 16'h0000;
end else begin
case (ab)
3'b000:outa <= db;
3'b001:outb <= db;
3'b010:outc <= db;
3'b011:outd <= db;
3'b100:oute <= db;
3'b101:outf <= db;
3'b110:outg <= db;
3'b111:outh <= db;
default:;
endcase
end
end
//read data 根据地址线选择8个空间读取,每个空间 16位
always @(rd or !resetn)
begin
if(!resetn)indata <= 16'h0000;
else begin
case (ab)
3'b000:indata <= ina;
3'b001:indata <= inb;
3'b010:indata <= inc;
3'b011:indata <= ind;
3'b100:indata <= ine;
3'b101:indata <= inf;
3'b110:indata <= ing;
3'b111:indata <= inh;
default:;
endcase
end
end
endmodule
FMC通信协议的FPGA代码

这里的FMC_A0表示的是地址线
这里有13位地址线和16位数据线,行地址与列地址是公用的,作为行地址时使用了0~12位,作为列地址时使用了0~8位;
- FMC_SDNWE:低电平时写,高电平时读;
-
FMC_SDNCAS:列地址选通信号,低电平有效;
-
FMC_SDNRAS:行地址选通信号,低电平有效;
-
FMC_SDNE0:片选信号,低电平有效;
-
FMC_BA0~1 :Bank选择信号,两位对应4个区域
-
FMC_SDCKE0:时钟使能信号;
-
FMC_SDCLK:时钟信号;
-
FMC_NBL0~1 :写访问的输出字节屏蔽,数据掩码
在我们板子中用到的

这实际上是FMC控制器对内核地址映射的结果,其实质就是对于地址的控制。
那么有没有简单的方法呢? 有的! STM32自带的FSMC功能,就是专门为这类存储器设计的,在STM32上,有一些引脚被专门设计成地址线,还有一些被专门设计成数据线,还有一些被设计成控制线,然后这些地址线和数据线对应着固定的地址,只要外部的DRAM等存储器将对应的数据线连接到STM32这些对应的引脚上,引脚功能设置为复用模式,通过配置FSMC ,你可以直接给上面那个固定的地址赋值 ,其他操作STM32都会自动给你完成,就可以把数据存储到SRAM中!
这里FPGA的通信也是如此,在配置好引脚后对其进行自动赋值,然后再对地址进行读写操作
在高云这里,有二十二个引脚需要我们去配置。
这个是目前对于Muxed PSRAM的配置


这里我们重点挑出
FMC_NL,
FMC_NOE,
FMC_NWE,
FMC_NE2
进行研究。 这里一共有20个引脚
对应一下FPGA的

FPGA这里除了数据线外多了
RST
FPGA_WR_NWE
FPGA_RD_NOE
FPGA_NL_NADV
FPGA_CS_NEL
CLK
这里有22个引脚,我们可以发现,这里多了两个引脚,一个是由rll来进行时钟控制,还有一个则是用于硬件的复位重启。