Ads 468x60px

Jumat, 08 Juni 2012

Cross-Clock Domain Signal Processing MCU based on FPGA

The signal processing in asynchronous domain is a key technology in a FPGA design, and it is the main reason why many engineers are discouraged upon FPGA. Is it really so mysterious?

First of all, this project is an application based on SCM (Single Chip Machine). Here let’s have a look at a read & write timing diagram of 11.0592MHz 51 SCM.
Our job now is to work as a slave machine of MCU and simulate an extend RAM for MCU. If MCU sends a write timing, FPGA should latch the data when it is more stable than data bus. If MCU sends a read timing, FPGA should put the data on the data bus before MCU establishing the data latch, and will be able to withdraw the data only after the holding time of data latch. Basically, this is all we need to do.

In fact, the time duration of MCU read and write is sufficient, because we use 50MHz crystal in our FPGA. Hence, a basic idea is that we need to synchronize the signal at MCU to the clock domain of FPGA, in order to achieve synchronized processing of asynchronous signals.

Verilog code
//----------------------------------------------------------------------
//----------------------------------------------------------------------
input clk;           //50MHz
input rst_n;      //reset signallow is effective

input mcu_cs_n;                //MCU chip select signallow is effective
input mcu_wr_n;               //MCU write signallow is effective
input[3:0] mcu_addr;       //MCU address bus
input[7:0] mcu_db;           //MCU data bus

reg[3:0] mcu_addr_r;      //mcu_addr register
reg[7:0] mcu_db_r; // mcu_db register

//////when mcu_cs_n and mcu_wr_n are pulled down together, pull down wr_state
wire  wr_state = mcu_cs_n || mcu_wr_n;   //write state bit

always @ (posedge clk or negedge rst_n)
         if(!rst_n) begin
                            mcu_addr_r <= 4’h0;
                            mcu_db_r <= 8’h00;
                  end
         else if(!wr_state) begin
                            mcu_addr_r <= mcu_addr;// mcu_addr register
                            mcu_db_r <= mcu_db;// mcu_db register
                   end

wire pos_wr;   //
reg wr1,wr2;   // MCU write state register
always @ (posedge clk or negedge rst_n)
         if(!rst_n) begin
                            wr1 <= 1'b1;    
                            wr2 <= 1'b1;
                   end
         else begin
                            wr1 <= wr_state;
                            wr2 <= wr1;
                   end

assign pos_wr = ~wr2 && wr1;       //

Tidak ada komentar:

Posting Komentar