一、硬件说明
- FSMC配置
单片机的代码如下:
#define VALUE_ADDRESS_AD1 (__IO uint16_t *)0x60400000
while (1)
{
if(!HAL_GPIO_ReadPin(GPIOF, GPIO_PIN_8)) //数据非空
{
data = *(__IO uint16_t *)VALUE_ADDRESS_AD1;
data2 = *(__IO uint16_t *)VALUE_ADDRESS_AD1;
printf("fsmc rd %d:%d\r\n",data,data2);
HAL_Delay(10);
}
}
- FPGA代码
//
// Description: 数据传入32位的FIFO, 用FSMC分2次读出
//
module fifo_32_fsmc_rd(
input clk,
input reset_n,
input fsmc_noe, //read signal
output led,
output fifo_empty,
output reg [15:0]fsmc_data
);
parameter WR_CNT = 5'd30-1;//写入30组数据
wire empty;
assign fifo_empty = empty;
assign led =!empty; //fifo有数据则灯亮,空则灭
assign rst = !reset_n;
//先往FIFO存入数据
wire wr_rst_busy;
reg [4:0]wr_cnt;//写入的数据进行计数
reg [3:0]state; //4种状态
parameter IDLE = 4'b0001,
READY =4'b0010,
WRITE =4'b0100;
always @(posedge clk or negedge reset_n)begin
if(!reset_n)
state<=IDLE; //空闲状态
else
case(state)
IDLE:
if(wr_rst_busy)
state<=IDLE;
else
state<=READY; //ready状态
READY:
if(wr_rst_busy)
state<=IDLE;
else if(empty)//若空则写入数据
state<=WRITE;
else
state<=READY;
WRITE:
if(wr_cnt < WR_CNT)
state <= WRITE;
else
state <= READY;
default: state<=IDLE;
endcase
end
reg wr_en;
always @(posedge clk or negedge reset_n)begin
if(!reset_n)begin
wr_cnt <= 5'd0;
wr_en <= 1'b0;
end
else if(state == WRITE)begin
wr_en <= 1'b1;
wr_cnt <= wr_cnt+1'b1;
end
else if(state == READY)begin
wr_cnt <= 5'd0;
wr_en <= 1'b0;
end
end
reg [31:0]din ;//fifo输入数据累加
always @(posedge clk or negedge reset_n)begin
if(!reset_n)
din <=32'd0;
else if(state == WRITE)
din <= din +1'b1;
else
din <= din ;
end
//从FIFO开始往外读出
wire [7:0]wr_data_count;
//fsmc_noe下降沿检测
reg reg_fsmc_noe1;
reg reg_fsmc_noe2;
wire falling_fsmc_noe;
always @(posedge clk)begin
reg_fsmc_noe1 <= fsmc_noe;
reg_fsmc_noe2 <= reg_fsmc_noe1;
end
assign falling_fsmc_noe = ((!reg_fsmc_noe1) & reg_fsmc_noe2);
wire [15 : 0] dout;
wire rd_rst_busy;
always @(posedge clk )
fsmc_data <= dout;
fifo_generator_0 fifo_32in (
.clk(clk), // input wire clk
.rst(rst), // input wire rst
.din(din), // input wire [31 : 0] din
.wr_en(wr_en), // input wire wr_en
.rd_en(falling_fsmc_noe), // input wire rd_en
.dout(dout), // output wire [15 : 0] dout
.full(), // output wire full
.empty(empty), // output wire empty
.wr_data_count(wr_data_count), // output wire [7 : 0] wr_data_count
.wr_rst_busy(wr_rst_busy), // output wire wr_rst_busy
.rd_rst_busy(rd_rst_busy) // output wire rd_rst_busy
);
endmodule
配置FIFO
写FIFO测试
`timescale 1ns / 1ps
module fifo_32_fsmc_rd_tb();
reg clk,noe,reset_n;
wire fifo_empty;
initial clk=1'b1;
always #10 clk= ~clk;
initial begin
reset_n = 1'b0;
noe=1;
#51;
reset_n = 1'b1;
#10000;
$stop;
end
fifo_32_fsmc_rd fifo_32_fsmc_rd1(
.clk(clk),
.reset_n(reset_n),
.fsmc_noe(noe), //read signal
.led(),
.fifo_empty(fifo_empty),
.fsmc_data()
);
endmodule
2. 最终单片机读到数据的实验结果, 只截取部分数据
smc rd 0:88
fsmc rd 0:89
fsmc rd 0:90
fsmc rd 0:91
fsmc rd 0:92
fsmc rd 0:93
fsmc rd 0:94
fsmc rd 0:95
fsmc rd 0:96
fsmc rd 0:97
fsmc rd 0:98
fsmc rd 0:99
fsmc rd 0:100
fsmc rd 0:101
fsmc rd 0:102
fsmc rd 0:103
fsmc rd 0:104
fsmc rd 0:105
fsmc rd 0:106
fsmc rd 0:107
fsmc rd 0:108
fsmc rd 0:109
fsmc rd 0:110
fsmc rd 0:111
fsmc rd 0:112
fsmc rd 0:113
fsmc rd 0:114
fsmc rd 0:115
fsmc rd 0:116
fsmc rd 0:117
fsmc rd 0:118
fsmc rd 0:119
fsmc rd 0:120
fsmc rd 0:121
fsmc rd 0:122
fsmc rd 0:123
fsmc rd 0:124
fsmc rd 0:125
fsmc rd 0:126
fsmc rd 0:127
fsmc rd 0:128
fsmc rd 0:129
fsmc rd 0:130
读出的数据正常