第一步,拷贝出example过程到自己的目录下(备份及解除只读)。
第二部打开工程,platformio.ini增加两行,name和dir,表示生产的逻辑目录logic和逻辑程序主程序的文件名analog_ip.v。
第三步,VE文件修改引脚映射。platform IO 哪里prepare LOGIC,生成逻辑程序
第四步,打开目录下的项目,记得一定要13.0的quartus。 quartus 18试过不行。
第5步,用tcl工具run一下。(不run好像编译出来的没有逻辑单元使用,即空程序)
第六步,移植代码
- module analog_ip (
- output tri0 TEST_LED,
- output tri0 UART_TX,
- input sys_clock,
- input bus_clock,
- input resetn,
- input stop,
- input [1:0] mem_ahb_htrans,
- input mem_ahb_hready,
- input mem_ahb_hwrite,
- input [31:0] mem_ahb_haddr,
- input [2:0] mem_ahb_hsize,
- input [2:0] mem_ahb_hburst,
- input [31:0] mem_ahb_hwdata,
- output tri1 mem_ahb_hreadyout,
- output tri0 mem_ahb_hresp,
- output tri0 [31:0] mem_ahb_hrdata,
- output tri0 slave_ahb_hsel,
- output tri1 slave_ahb_hready,
- input slave_ahb_hreadyout,
- output tri0 [1:0] slave_ahb_htrans,
- output tri0 [2:0] slave_ahb_hsize,
- output tri0 [2:0] slave_ahb_hburst,
- output tri0 slave_ahb_hwrite,
- output tri0 [31:0] slave_ahb_haddr,
- output tri0 [31:0] slave_ahb_hwdata,
- input slave_ahb_hresp,
- input [31:0] slave_ahb_hrdata,
- output tri0 [3:0] ext_dma_DMACBREQ,
- output tri0 [3:0] ext_dma_DMACLBREQ,
- output tri0 [3:0] ext_dma_DMACSREQ,
- output tri0 [3:0] ext_dma_DMACLSREQ,
- input [3:0] ext_dma_DMACCLR,
- input [3:0] ext_dma_DMACTC,
- output tri0 [3:0] local_int
- );
-
-
- parameter ADDR_BITS = 16;
- parameter DATA_BITS = 32;
-
-
- wire apb_psel;
- wire apb_penable;
- wire apb_pwrite;
- wire [ADDR_BITS-1:0] apb_paddr;
- wire [DATA_BITS-1:0] apb_pwdata;
- wire [3:0] apb_pstrb;
- wire [2:0] apb_pprot;
- wire apb_pready = 1'b1;
- wire apb_pslverr = 1'b0;
- wire [DATA_BITS-1:0] apb_prdata;
-
-
-
- assign apb_clock = bus_clock;
-
-
-
- ahb2apb
- .reset (!resetn ),
- .ahb_clock (sys_clock ),
- .ahb_hmastlock(1'b0 ),
- .ahb_htrans (mem_ahb_htrans ),
- .ahb_hsel (1'b1 ),
- .ahb_hready (mem_ahb_hready ),
- .ahb_hwrite (mem_ahb_hwrite ),
- .ahb_haddr (mem_ahb_haddr[ADDR_BITS-1:0]),
- .ahb_hsize (mem_ahb_hsize ),
- .ahb_hburst (mem_ahb_hburst ),
- .ahb_hprot (4'b0011 ),
- .ahb_hwdata (mem_ahb_hwdata ),
- .ahb_hrdata (mem_ahb_hrdata ),
- .ahb_hreadyout(mem_ahb_hreadyout ),
- .ahb_hresp (mem_ahb_hresp ),
- .apb_clock (apb_clock ),
- .apb_psel (apb_psel ),
- .apb_penable (apb_penable ),
- .apb_pwrite (apb_pwrite ),
- .apb_paddr (apb_paddr ),
- .apb_pwdata (apb_pwdata ),
- .apb_pstrb (apb_pstrb ),
- .apb_pprot (apb_pprot ),
- .apb_pready (apb_pready ),
- .apb_pslverr (apb_pslverr ),
- .apb_prdata (apb_prdata )
- );
-
- //��������֣�һ����mcu��ahb���ź�(mem_ahb_xxxx)��һ����ahbתapb֮�����źţ�apb_xxxx)
- //�������£�����ֱ��ʹ��apb_xxxx�źţ���ѭAPBЭ�鼴�ɡ�
-
-
- parameter UART_ADDR = 'h6000;
-
-
- parameter ADDR_UART_DATA = 'h00; //д�ļĴ���
- parameter ADDR_UART_STAT = 'h04;
-
-
-
- reg TestLedCtrl = 1;
-
-
- reg uart_start;
- reg uart_reset;
- reg[7:0] uart_write;
- wire tx_busy;
- wire tx_complete;
- wire uart_tx_line;
- reg [31:0] prdata;
-
-
-
-
- assign UART_TX = uart_tx_line;
- wire apb_data_phase = apb_psel && apb_penable;
- assign apb_prdata = prdata;
-
-
- always @ (posedge apb_clock or negedge resetn) begin
- if (!resetn)
- begin
- uart_reset <= 0;
- uart_start <= 0;
- end
-
-
- else if (apb_data_phase && apb_pwrite && apb_paddr == UART_ADDR + ADDR_UART_DATA)
- begin
-
- uart_write <= apb_pwdata[7:0];
- uart_start <= 1;
- uart_reset <= 1;
- end
-
-
- else if (apb_data_phase && !apb_pwrite && apb_paddr == UART_ADDR + ADDR_UART_STAT)
- begin
- prdata <= {30'b0, tx_complete, tx_busy}; //����λΪbusyλ�������ڶ�λΪtcλ����30λ��Ч
- //if (uart_txComplete == 1) TestLedCtrl <= 1; //led����
- end
- else
- begin
- uart_start <= 0;
- end
- end
-
-
- //������uart����ģ��
- //����ģ���ڵ�ʵ�������Ǹ�״̬����
- // ��һ��byte�����̲��ֳ�5���Σ���������������ݣ�7��bit��������1��bit��������
- // ����������start�ź��������
- // Ȼ������clock�ļ��������״̬�����ղ����ʼ���ÿ��bitҪ���ѵ�clock���������������¸�bit...��
- // ��������2��bit����stopλ�����������̽�����
- //������ͺ���busy״̬λ����1��ȫ���������ɺ�״̬λ���û�0
- uart_tx uart_tx_ins
- (
- .reset_n (uart_reset),
- .clk (apb_clock),
- .start (uart_start),
- .registor (uart_write),
- .uart_tx (uart_tx_line),
- .uart_tc (tx_complete),
- .uart_busy (tx_busy)
- );
-
- RUN_LED led_module(
- .clk_100M(apb_clock),
- .rset_n(uart_reset),
- .LED(TEST_LED)
- );
- endmodule
-
-
-
- module RUN_LED(
- input clk_100M,
- input rset_n,
- output LED
- );
-
- reg ledreg=1'd0;
- reg[25:0] clknum;
- reg[25:0] ledclknum=26'd0;
-
- parameter ledclk_50hz = 25'd25000000;
-
- always @(posedge clk_100M ,negedge rset_n )
- if(!rset_n)
- begin
- ledclknum <=26'd0;
- ledreg <=1'd0;
- end
- else
- begin
- ledclknum = ledclknum+1'd1;
- if(ledclknum > ledclk_50hz )
- begin
- ledreg <= ~ledreg ;
- ledclknum <=26'd0;
- end
- end
- assign LED=ledreg;
-
- endmodule
-
第7步 ,quartus编译一遍,编译完成看到使用逻辑225,然后用Surpra工具打开目录下的项目,Compile一下。此时固件生成完成。
第8步,回到Vscode,UpLoad Logic就能看到闪灯了。然后将Uart Tx的代码移植如下
- #include "example.h"
-
- void Button_isr(void)
- {
- if (button_isr_cb) {
- button_isr_cb();
- }
- UTIL_IdleMs(400);
- GPIO_ClearInt(BUT_GPIO, BUT_GPIO_BITS);
- }
-
- void MTIMER_isr(void)
- {
- GPIO_Toggle(EXT_GPIO, EXT_GPIO_BITS);
- INT_SetMtime(0);
- }
-
- void TestMtimer(int ms)
- {
- clint_isr[IRQ_M_TIMER] = MTIMER_isr;
- INT_SetMtime(0);
- INT_SetMtimeCmp(SYS_GetSysClkFreq() / 1000 * ms);
- INT_EnableIntTimer();
- while (1);
- }
-
-
-
- #define RD_STATE_BUSY 0x01
- #define RD_STATE_TC 0x02
- typedef struct
- {
- __IO uint32_t DAT;
- __IO uint32_t STA;
- } UARTOWN_TypeDef;
-
- #define UART ((UARTOWN_TypeDef *) 0x60006000) //cpld中该“外设”的地址
-
-
-
- int main(void)
- {
-
- board_init();
-
-
-
- plic_isr[BUT_GPIO_IRQ] = Button_isr;
-
- INT_SetIRQThreshold(MIN_IRQ_PRIORITY);
-
- INT_EnableIRQ(BUT_GPIO_IRQ, PLIC_MAX_PRIORITY);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- volatile int regState = 0;
- while(1)
- {
- for (int i = 1; i < 255; i++)
- {
- while((UART->STA) & RD_STATE_BUSY);
- UART->DAT = i;
- while(!((UART->STA) & RD_STATE_TC));
- UTIL_IdleUs(100e3);
- }
- }
-
- TestGpio();
- }
-
编译,下载,打开下载器的串口,有信号=成功
附件是整体工程。收1积分辛苦费
参考文档。