溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

FPGA設計——SPI Flash啟動之MC8051設計

發(fā)布時間:2020-07-28 09:49:20 來源:網絡 閱讀:7085 作者:shugenyin 欄目:開發(fā)技術

1. 概述

本設計采用FPGA技術,在FPGA中實現(xiàn)8051單片機的軟核,將外部SPI Flash中的代碼數據加載到FPGA內部ram,然后復位MC8051,實現(xiàn)外部flash啟動MC8051。


2. 系統(tǒng)框圖

8051采用Oregano Systems公司開源的MC8051軟核。SPI Flash采用W25Q16芯片存儲8051的代碼程序。系統(tǒng)框圖如下:

FPGA設計——SPI Flash啟動之MC8051設計


3. MC8051簡介

Oregano Systems的8051單片機采用VHDL語言開發(fā),具有如下特點:

  • 采用完全同步設計

  • 指令集和標準 8051 微控制器完全兼容

  • 指令執(zhí)行時間為 1~4 個時鐘周期,執(zhí)行性能優(yōu)于標準 8051 微控制器 8 倍左右

  • 用戶可選擇定時器/計數器、串行接口單元的數量

  • 新增了特殊功能寄存器用于選擇不同的定時器/計數器、串行接口單元

  • 可選擇是否使用乘法器(乘法指令 MUL)

  • 可選擇是否使用除法器(除法指令 DIV)

  • 可選擇是否使用十進制調整功能(十進制調整指令 DA)

  • I/O 口不復用

  • 內部帶 256Bytes RAM

  • 最多可擴展至 64Kbytes 的 ROM 和 64Kbytes 的 RAM

  • 最多可擴展至 64Kbytes 的 ROM 和 64Kbytes 的 RAM

MC8051 IP Core的頂層結構如下圖所示:

FPGA設計——SPI Flash啟動之MC8051設計


4. MC8051移植

在mc8051_p.vhd中,更改C_IMPL_N_TMR、C_IMPL_N_SIU、C_IMPL_N_EXT的值可以定義定時器和外部中斷的數量。

  -----------------------------------------------------------------------------
  -- Select how many timer/counter units should be implemented
  -- Default: 1
  constant C_IMPL_N_TMR : integer := 1;
  -----------------------------------------------------------------------------

  -----------------------------------------------------------------------------
  -- Select how many serial interface units should be implemented
  -- Default: C_IMPL_N_TMR ---(DO NOT CHANGE!)---		     
  constant C_IMPL_N_SIU : integer := C_IMPL_N_TMR;
  -----------------------------------------------------------------------------
				     
  -----------------------------------------------------------------------------
  -- Select how many external interrupt-inputs should be implemented
  -- Default: C_IMPL_N_TMR ---(DO NOT CHANGE!)---
  constant C_IMPL_N_EXT : integer := C_IMPL_N_TMR;
  -----------------------------------------------------------------------------

在mc8051_p.vhd中,還可以選擇需要的指令,可選的指令有MUL/DIV/DA。

  -----------------------------------------------------------------------------
  -- Select whether to implement (1) or skip (0) the multiplier
  -- Default: 1
  constant C_IMPL_MUL : integer := 1;
  -----------------------------------------------------------------------------

  -----------------------------------------------------------------------------
  -- Select whether to implement (1) or skip (0) the divider
  -- Default: 1
  constant C_IMPL_DIV : integer := 1;
  -----------------------------------------------------------------------------
				   
  -----------------------------------------------------------------------------
  -- Select whether to implement (1) or skip (0) the decimal adjustment command
  -- Default: 1
  constant C_IMPL_DA  : integer := 1;
  -----------------------------------------------------------------------------

在FPGA中用內部的ram資源構建一個rom和一個ram以供8051使用,其中rom需為雙端口,用于spi_flash_controller加載flash中的程序。


5. SPI Flash簡介

SPI Flash芯片是由8192個頁組成,每頁大小為256字節(jié)。16頁組成一個扇區(qū),128/256頁組成一個塊,其結構框圖如下:

FPGA設計——SPI Flash啟動之MC8051設計

SPI Flash的讀寫指令如下:

FPGA設計——SPI Flash啟動之MC8051設計

FPGA設計——SPI Flash啟動之MC8051設計


6. SPI Flash控制器設計

SPI Flash的讀寫時序如下:其他操作的時序可查看spi flash datasheet。

FPGA設計——SPI Flash啟動之MC8051設計

FPGA設計——SPI Flash啟動之MC8051設計

控制器狀態(tài)機設計如下:

FPGA設計——SPI Flash啟動之MC8051設計


SPI Flash加載控制邏輯代碼如下:

//file name:	spi_flash_load.v
//author:		shugen.yin
//date:			2017.1.5
//function:		load code from spi flash to dram
//log:

module spi_flash_load(
	//Global signal
	input clk,
	input rst_n,

	//signal from and to SPI reader
	output reg rd_start,
	output reg [31:0] rd_addr,
	output reg [31:0] rd_length,
	input      [7:0] rd_data,
	input      rd_data_valid,
	input      read_busy,
	
	//signal to mc8051
	input      [15:0] rdaddress,
	output     [7:0]  data_out,
	output     reg    reset

);

reg [15:0] wraddress;

always @(posedge clk)
	if(rd_data_valid)
		wraddress <= wraddress + 1'b1;
	else
		wraddress <= wraddress;
		

dpram	dpram_inst (
	.clock ( clk ),
	.data ( rd_data ),
	.rdaddress ( rdaddress ),
	.wraddress ( wraddress ),
	.wren ( rd_data_valid ),
	.q ( data_out )
	);

reg [15:0] spi_cnt;

always @(posedge clk)
	if(spi_cnt<=16'h0fff)
		spi_cnt <= spi_cnt + 1'b1;
	else
		spi_cnt <= spi_cnt;

always @(posedge clk)
	if(spi_cnt==1)
	begin
		rd_start <= 1'b1;
		rd_addr  <= 'h0;
		rd_length<= 'h2000;
	end
	else
	begin
		rd_start <= 1'b0;
		rd_addr  <= rd_addr;
		rd_length<= rd_length;	
	end	

	
always @(posedge clk)
	if(spi_cnt==16'h2000)
	   reset <= 0;
	else
		reset <= 1'b1;

endmodule


7. MC8051 C語言開發(fā)

這里采用Keil uVision4作為開發(fā)平臺,用到MC8051的I/0和定時器設備,代碼設計如下:

#include <reg51.h>

sbit P00=P0^0;

char i=100;

unsigned char led=0;

void Timer0_init(void)
{
	TMOD = 0x01;	//set timer0 as mode-1
	TH0  = 0xee;	
	TL0  = 0x00;
	P00  = 0;
	EA   = 1;		//enable interrupt
	ET0  = 1;		//enable timer0 interrupt
	TR0  = 1;		//Trigger Timer0	
}

void main(void)
{
	Timer0_init();

	while(1){};
}

void Timer0_int(void) interrupt 1
{
	TH0 = 0xee;
	TL0 = 0x00;
	i--;
	if(i<=0)
	{
		led  = ~led;
		i    = 100;
	}	
	P00 = led;
}

編譯KEIL工程,得到hex文件:將KEIL生成的hex文件燒寫道SPI Flash中。

FPGA設計——SPI Flash啟動之MC8051設計


8. FPGA系統(tǒng)邏輯代碼設計

FPGA系統(tǒng)邏輯代碼頂層設計如下:

//file name			: top_fpga.v
//data				: 2017.1.9
//author			: shugen.yin
//function			: top of project
//log				:

module top_fpga(
	//global signal
	input clk,
	input rst_n,
	
	//led
	output [1:0] led
	);

//----------------MC8051------------------
wire int0_i;
wire int1_i;
wire all_t0_i;
wire all_t1_i;
wire [7:0] p0_i;
wire [7:0] p1_i;
wire [7:0] p2_i;
wire [7:0] p3_i;

(* keep *)wire [7:0] p0_o;
(* keep *)wire [7:0] p1_o;
(* keep *)wire [7:0] p2_o;
(* keep *)wire [7:0] p3_o;

mc8051_top mc8051_top_inst
(
	.clk(clk) ,	// input  clk_sig
	.reset(spi_load_reset) ,	// input  reset_sig
	.int0_i(int0_i) ,	// input [0:0] int0_i_sig
	.int1_i(int1_i) ,	// input [0:0] int1_i_sig
	.all_t0_i(1'b0) ,	// input [0:0] all_t0_i_sig
	.all_t1_i(1'b0) ,	// input [0:0] all_t1_i_sig
	.p0_i(p0_i) ,	// input [7:0] p0_i_sig
	.p1_i(p1_i) ,	// input [7:0] p1_i_sig
	.p2_i(p2_i) ,	// input [7:0] p2_i_sig
	.p3_i(p3_i) ,	// input [7:0] p3_i_sig
	.p0_o(p0_o) ,	// output [7:0] p0_o_sig
	.p1_o(p1_o) ,	// output [7:0] p1_o_sig
	.p2_o(p2_o) ,	// output [7:0] p2_o_sig
	.p3_o(p3_o) , 	// output [7:0] p3_o_sig
	
	.dram_adr_o(spi_load_address) ,	//output address
	.dram_data_i(spi_load_data)		//input data
);

assign led = {p0_o[0],~p0_o[0]};

//----------------SPI Flash------------------
wire 			rd_start;
wire [31:0] rd_addr;
wire [31:0] rd_length;
wire [7:0]  rd_data;
wire 		rd_data_valid;
wire		read_busy;

spi_flash_reader spi_flash_reader_inst
(
	//global signal
	.clk(clk),
	.rst_n(rst_n),
	
	//SPI master port
	.spi_dclk(flash_clk),
	.spi_cs_n(flash_cs_n),
	.spi_so(flash_mosi),
	.spi_si(flash_miso),
	
	//export port
	.rd_start(rd_start),
	.rd_addr(rd_addr),
	.rd_length(rd_length),
	.rd_data(rd_data),
	.rd_data_valid(rd_data_valid),
	.read_busy(read_busy)
);

wire [15:0] spi_load_address;
wire [7:0]  spi_load_data;
wire        spi_load_reset;

spi_flash_load spi_flash_load_inst
(
	.clk(clk) ,	                    // input  clk_sig
	.rst_n(rst_n) ,	                // input  rst_n_sig
	.rd_start(rd_start) ,           // output  rd_start_sig
	.rd_addr(rd_addr) ,	            // output [31:0] rd_addr_sig
	.rd_length(rd_length) ,         // output [31:0] rd_length_sig
	.rd_data(rd_data) ,	            // input [7:0] rd_data_sig
	.rd_data_valid(rd_data_valid) ,	// input  rd_data_valid_sig
	.read_busy(read_busy) ,	        // input  read_busy_sig
	.rdaddress(spi_load_address) ,	// output [11:0] rdaddress_sig
	.data_out(spi_load_data), 	    // output [7:0] data_out_sig
	.reset(spi_load_reset)
);

endmodule


9. 最終結果

在Quartus II 13.1平臺下,編譯完成后,將sof文件下載到板卡上,LED交替閃爍。

FPGA設計——SPI Flash啟動之MC8051設計



向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI