FPGA implementation of EXMC parallel port communication timing of Huada Semiconductor HC32F4A0 series ARM chip

FPGA implementation of EXMC parallel port communication timing of Huada Semiconductor HC32F4A0 series ARM chip

Introduction to EXMC

The external memory controller EXMC is an independent module used to access various off-chip memories and implement data exchange. EXMC can convert the internal AMBA protocol interface into various types of dedicated off-chip memory communication protocol interfaces through configuration.
Among them, the SRAM/PSRAM/NOR Flash controller is defined as SMC (Static Memory Controller), the SDRAM controller is defined as DMC (Dynamic Memory Controller), and the NAND Flash controller is defined as NFC (NAND Flash Memory Controller). This article will be in FPGA Implement the SMC mode among the three modes.

EXMC-SMC read timing analysis

Insert image description here
Figure 4-2 shows the read timing of the EXMC parallel port of the ARM chip. The data bit width of the communication between the parallel port and the FPGA can be divided into 8 bits, 16 bits, and 32 bits. Specifically, this article will take 16-bit wide reception data (receiving 2 bytes of data at a time) as an example for analysis.
First, you need to understand the meaning of the interface signals in the picture. The signal SMC_CS is represented as a chip select signal, SMC_OE is a read enable signal, SMC_BLS is a byte strobe signal (this signal is not used in this design), SMC_ADD is an address signal, and SMC_DATA is 16-bit data.
The next step is to analyze the timing in the figure. It can be seen from the figure that the chip select signal SMC_CS remains low during the entire process of reading data, and will be locked at each falling edge of the read enable signal SMC_OE. Address operation (each falling edge locks an address), data will be read on each rising edge of SMC_OE (one 16-bit data is read on each rising edge), so it is relatively simple to convert the above analysis content into Verilog code.

EXMC-SMC write timing analysis

Insert image description here
Figure 4-3 shows the write timing of the EXMC parallel port of the ARM chip. The data bit width for communication between the parallel port and the FPGA can be divided into 8 bits, 16 bits, and 32 bits. Similarly, this article will take 16-bit wide sending data (sending 2 bytes of data at a time) as an example for analysis.
The signal SMC_CS represents the chip select signal, SMC_WE is the write enable signal, SMC_BLS is the byte strobe signal (this signal is not used in this design), SMC_ADD is the address signal, and SMC_DATA is 16-bit data.
As can be seen from the figure, the chip select signal SMC_CS remains low during the entire process of writing data, and the address lock operation will be performed on the falling edge of the write enable signal SMC_WE. What needs to be noted here is. When performing an address lock operation, it will continuously give 4 addresses (Add, Add+1, Add+2, Add+3 in the picture), but at this time only the data corresponding to the first address Add is valid, and then The data corresponding to the three addresses are all in the indefinite state X, so in the write sequence, we only lock the first address at the falling edge of each write enable, and write out the data corresponding to this address. Next is the Verilog implementation of EXMC read and write timing.

EXMC-SMC read and write timing Verilog implementation

module HC32_EXMC_SMC #(
	parameter AD_WIDTH = 12,
	parameter DATA_WIDTH = 16,
)(
	input wire clk,
	input wire rst,	
	inout wire [15:0] ARM_DATA_Inout,
	input wire [AD_WIDTH -1:0] ARM_ADDR_In,
	input wire ARM_NOE_In,
	input wire ARM_NWE_In,
	input wire ARM_NCE_In,
	
	output reg [AD_WIDTH -1:0] FPGA_ad,
	input wire [DATA_WIDTH -1:0] FPGA_data_in,
	output reg [DATA_WIDTH -1:0] FPGA_data_out
);

reg noe;
reg noe_dly1;
reg noe_diy2;
reg nwe_dly1;
reg nwe_diy2;
reg nce_dly1;
reg nce_diy2;
reg noe_neg;
reg nce_neg;
reg nwe_neg;
reg nwe_cnt;

//第一步:取片选、读写使能边沿、打拍防止亚稳态
always @(posedge clk)
begin
	if(rst)
	begin
		noe_dly1 <= 1;
		noe_dly2 <= 1;
	end
	else
	begin
		noe_dly1 <= ARM_NOE_In;						//读使能打两拍
		noe_dly2 <= noe_dly1  ;
		noe_neg  <= noe_dly2  & ~noe_dly1;		//取读使能下降沿
		noe_pos  <= ~noe_dly2  & noe_dly1;		//取读使能上升沿
	end
end

always @(posedge clk)
begin
	if(rst)
	begin
		nwe_dly1 <= 1;
		nwe_dly2 <= 1;
		nce_dly1 <= 1;
		nce_dly2 <= 1;
	end
	else
	begin
		nce_dly1 <= ARM_NCE_In;					//片选信号打两拍
		nce_dly2 <= nce_dly1  ;
		nce_neg  <= nce_dly2  & ~nce_dly1;	//取片选下降沿

		nwe_dly1 <= ARM_NWE_In;				//写使能打两拍
		nwe_dly2 <= nwe_dly1  ;
		nwe_neg  <= nwe_dly2  & ~nwe_dly1;	//取写使能下降沿
	end
end

//第二步:锁读写地址
always @(posedge clk)
begin
	if(rst)
		nwe_cnt <= 2'b0;
	else if(nce_neg)
		nwe_cnt <= 2'b0;
	else if(nwe_neg && !nce_dly1)	
		nwe_cnt <= nwe_cnt +1'b1;	
	else if(nwe_cnt== 2'd4)				//会给出连续4个地址,只锁第一个地址,后三个地址无效
		nwe_cnt <= 2'b0;				
	else
		nwe_cnt <=nwe_cnt ;				
end

always @(posedge clk)
begin
	if(nce_dly1 == 0)
	begin
		if((noe_neg) || (nwe_neg && (nwe_cnt  == 0)))			//会给出连续4个地址,只锁第一个地址,后三个地址无效
		begin
			FPGA_ad <= ARM_ADDR_In;				
		end
	end			
end

//写数据
always @(posedge clk)
begin
	if(nce_dly1 == 0)
	begin
		if(nwe_neg  && (nwe_cnt  == 0))			
		begin
			FPGA_data_out<= ARM_DATA_Inout;				
		end
	end			
end

//读数据
always @(posedge clk)
begin
	if(rst)
	begin
		noe <= 1;
	end
	else
	begin
		if(!nce_dly1 && noe_pos)
		begin
			noe <= 0;
		end
		else if(nce_dly1 && !noe_pos)
			noe <= 1;
		else
			noe <= noe;
	end		
end

assign ARM_DATA_Inout = (ARM_NCE_In ==0 && noe == 0) ? FPGA_data_in :'bz;

endmodule

EXMC read and write timing simulation waveform diagram

Insert image description here

The figure shows the read and write timing simulation waveform diagram of the EXMC interface, which is consistent with the timing in the data sheet.

Guess you like

Origin blog.csdn.net/m0_51575600/article/details/130712494