【iCore4 双核心板_FPGA】例程十六:基于双口RAM的ARM+FPGA数据存取实验
实验现象:
核心代码:
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链接: