【iCore4 雙核心板_FPGA】例程十六:基於雙口RAM的ARM+FPGA資料存取實驗

XiaomaGee發表於2017-09-27

實驗現象:

 

核心程式碼:

int main(void)
{

  /* USER CODE BEGIN 1 */
    int i;
    int address,data;
    char error_flag = 0;
    char receive_data[50];
    char buffer[8];
    char *p;
  /* USER CODE END 1 */

  /* MCU Configuration----------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_USART6_UART_Init();
  MX_FMC_Init();

  /* USER CODE BEGIN 2 */
    usart6.initialize(115200);
    usart6.printf("Hello, I am iCore4!\r\n");
    LED_GREEN_ON;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while (1)
  {
  /* USER CODE END WHILE */

  /* USER CODE BEGIN 3 */
        if(usart6.receive_ok_flag == 1){
            usart6.receive_ok_flag = 0;
            memset(receive_data,0,sizeof(receive_data));
            memset(buffer,0,sizeof(buffer));
            for(i = 0;i < 30;i ++){
                receive_data[i] = usart6.receive_buffer[i];
            }
            p = receive_data;
            i = 0;
            while(*p != ':'){                                    //»ñÈ¡²Ù×÷ÃüÁwrite or read£©
                buffer[i++] = *p++;
                if(i > sizeof(buffer))i = 0;
            }
            for(i = 0;i < sizeof(buffer);i++){//½«ÃüÁîת»¯ÎªÐ¡Ð´×Ö·û
                buffer[i] = tolower(buffer[i]);
            }

            if(memcmp(buffer,"read",strlen("read")) == 0){//Ö´ÐжÁ²Ù×÷
                error_flag = 0;
                p++;
                address = atoi(p);
                if(address > 255)error_flag = 1;
                p++;
                if(strchr(p,','))error_flag = 1;
                if(!error_flag){
                    data = fpga_read(address);
                    usart6.printf("Read FPGA Ram:%d\r\n",data);
                }                    
            }else{
                error_flag = 1;
            }
            
            if(error_flag){
                LED_RED_ON;
                LED_GREEN_OFF;
                usart6.printf("Bad Command!\r\n");
            }else{
                LED_RED_OFF;
                LED_GREEN_ON;
            }
        }
  }
  /* USER CODE END 3 */

}
module dual_port_ram_ctrl(
    input clk_25m,
    input rst_n,
    input wrn,
    input rdn,
    input cs0,
    inout [15:0]db,
    input [23:16]ab,
    output led_red,
    output led_green,
    output led_blue
);

//-----------------------------ram-----------------------------//
wire [15:0]dataout_a;
wire [15:0]dataout_b;

ram u1(
    .data_a(data_a),
    .address_a(address_a),
    .wren_a(wren_a),
    .rden_a(rden_a),
    .clock_a(!clk_a),
    .q_a(dataout_a),
    
    .data_b(db),
    .address_b(ab),
    .wren_b(1'd0),
    .rden_b(!rd),
    .clock_b(clk_b),
    .q_b(dataout_b)
);

//-----------------------------clk_100m-----------------------------//

pll u2(
    .inclk0(clk_25m),
    .c0(clk_100m)
);

//-------------------------------clk_a-----------------------------//
reg clk1,clk2;
always@(posedge clk_100m or negedge rst_n)
    if(!rst_n)
        begin
            clk1 <= 1'd0;
            clk2 <= 1'd0;
        end
    else 
        {clk2,clk1} <= {clk1,clk_25m};
        
wire clk_a = (clk_25m & clk1);

//-------------------------------data-----------------------------//
reg [9:0]data;
always@(posedge clk_25m or negedge rst_n)
    if(!rst_n)
        data <= 10'd0;
    else if(data == 10'd511)
        data <= 10'd0;
    else 
        data <= data + 1'd1;
        
//-------------------------write & read port a-------------------//
reg wren_a;
reg rden_a;
reg [9:0]data_a;
reg [9:0]address_a;

always@(posedge clk_a or negedge rst_n)
    if(!rst_n)
        begin
            wren_a <= 1'd0;
            rden_a <= 1'd0;
            data_a <= 10'd0;
            address_a <= 10'd0;
        end
    else if(data >= 10'd0 && data <= 10'd255)
        begin
            wren_a <= 1'd1;
            rden_a <= 1'd0;
            data_a <= data;
            address_a <= data;
        end
    else if(data >= 10'd256 && data <= 10'd511)
        begin
            wren_a <= 1'd0;
            rden_a <= 1'd1;
            address_a <= data - 10'd256;
        end

//-----------------------------ram a---------------------------//
reg error;

always@(negedge clk1 or negedge rst_n)
    if(!rst_n)
            error <= 1'd0;
    else
        begin
            if(wren_a || dataout_a == address_a)
                error <= 1'd0;
            else
                error <= 1'd1;
        end

//--------------------------ram_a_led---------------------------//
reg ledr,ledg,ledb;
always@(posedge error or negedge rst_n)
    if(!rst_n)
        begin
            ledr <= 1'd1;
            ledg <= 1'd0;
            ledb <= 1'd1;    
        end
    else
        begin
            ledr <= 1'd0;
            ledg <= 1'd1;
            ledb <= 1'd1;            
        end    
assign {led_red,led_green,led_blue} = {ledr,ledg,ledb};

//--------------------------ram_b_rd----------------------------//
wire rd = (cs0 | rdn);
wire wr = (cs0 | wrn);

reg wr_clk1,wr_clk2;
always@(posedge clk_100m or negedge rst_n)
    if(!rst_n)
        begin
            wr_clk1 <= 1'd1;
            wr_clk2 <= 1'd1;
        end
    else 
        {wr_clk2,wr_clk1} <= {wr_clk1,wr};
        
wire clk_b = (!wr_clk2 | !rd);
assign db = !rd ? dataout_b : 16'hzzzz;
        
endmodule

原始碼下載連結:

連結:http://pan.baidu.com/s/1qYqNlwg 密碼:9il4

iCore4連結:

相關文章