<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                [TOC] > # 簡介 近段時間做項目,涉及到一些傳感器數據的采集,比如溫度傳感器`DHT11`,這種東西使用FPGA來做,為了實現他的時序,如果自己寫的話那是真的不容易,但是對于項目來說,這個東西有需要做,怎么辦?于是在FPGA或者CPLD中做一個占用資源可控,且能在各個平臺下移植的可編程狀態機就進入了我的視野。 說時遲那時快,花了一天時間寫了一個簡單的8位mcu,在功能上僅僅只有簡單的輸入輸出功能,加減法,邏輯運算,支持跳轉,調用,比較等指令。 > # 主要實現功能 目前該mcu的主要情況如下: * 內部16個寄存器,s0 ~ sF * 設計一個深度為31的程序指針棧,用于支持CALL命令 * 支持8位加減法運算,通過設計的標志位可以實現16為,32位的加減法運算 * 支持邏輯運算,AND,OR,XOR * 有一個中斷輸入口 * 可在mcu外部使用邏輯資源擴展中斷--利用標志位的方式 從實現功能上來看,似乎比較少,但是我們依舊可以使用這些有限的命令實現我們的初衷,就是實現與一些簡單傳感器的交互,甚至可以實現I2C,SPI的通信接口。 在指令上為了不用自己開發將匯編翻譯為機器指令的工具,這里直接和xilinx的picoblaze的指令保持一致,換句話說,使用xilinx的工具可以將我們的匯編代碼翻譯成支持這個mini-mcu的機器指令。 > # 有什么特有的特性 在一些資源有限的CPLD上,完全實現一個mcu是不現實,為了契合我的初衷,并且不讓資源被浪費太多,我字節寫了腳本,可以根據寫的匯編代碼,將匯編代碼中使用到的命令提取出來,并會直接將`mini-mcu`與這些命令有關的部分保留,**裁剪掉其他沒有用到的部分**,但是輸入輸出部分將會一直保留。另外由于沒有實現其他一些復雜的指令,**這些指令都是在兩個時鐘周期中完成的**,也就是說基于這個特性,可以實現精確的時鐘延時。 > # 環境準備 由于自己適應了linux的環境,所以實現的腳本都是使用`bash`寫的,包括裁剪mcu,如果不會linux指令也沒事,只不過不能自動化的生成這些東西,需要自己手動來,包括裁剪mcu,當然這種情況下,你可以不裁剪。 **說一說在為了支持linux指令,在windows系統上應該怎么準備環境** ## step1:安裝cygwin以支持bash腳本 Cygwin就是一個windows軟件,該軟件就是在windows上仿真linux操作系統 ,簡言之,cygwin是一個在windows平臺上運行的 linux模擬環境,使用一個Dll(動態鏈接庫)來實現 這樣,我們可以開發出Cygwin下的UNIX工具,使用這個DLL運行在Windows下。 **安裝方法** **1、下載`cygwin`安裝器** 下載地址:[官方地址](http://www.cygwin.com/) ![](https://img.kancloud.cn/6f/61/6f618d2eefc33b4d32f52f3d95b2afa8_1490x863.png) 然后就可以使用這個安裝器進行安裝了 **2、啟動安裝器進行安裝** 安裝器有三種安裝模式可供選擇: ``` ①Install from Internet,這種模式直接從Internet安裝,適合網速較快的情況; ②Download Without Installing,這種模式只從網上下載Cygwin的組件包,但不安裝; ③Install from Local Directory,這種模式與上面第二種模式對應,當你的Cygwin組件包已經下載到本地,則可以使用此模式從本地安裝Cygwin ``` ***說明:當你安裝過,在執行該安裝程序可以選擇本地安裝,然后添加需要擴展的命令。*** 第一次安裝使用第一種方式進行安裝: ![](https://img.kancloud.cn/80/f4/80f4c5a3d44b5644b59f5ae0b5f39544_990x658.png) ![](https://img.kancloud.cn/5a/1c/5a1c49a634392115421375a9a3ad6ad2_990x646.png) **在下載的同時,建議將Cygwin安裝組件也保存到了本地,以便以后能夠再次安裝,這一步選擇安裝過程中從網上下載的Cygwin組件包的保存位** ![](https://img.kancloud.cn/eb/a5/eba5b77b84a416d7aef02fd58dfca706_1001x664.png) **選擇連接方式** 這一步選擇連接的方式,選擇你的連接方式,然后點擊下一步,會出現選擇下載站點的對話框,如下圖所示 ![](https://img.kancloud.cn/0f/aa/0faa90208d28e288088db4cdaece16ef_975x590.png) ``` ①Use System Proxy Settings 使用系統的代理設置 ②Direct Connection 一般多數用戶都是這種直接連接的網絡,所以都是直接使用默認設置即可 ③Use HTTP/FTP Proxy 使用HTTP或FTP類型的代理。如果有需要,自己選擇此項后,設置對應的代理地址和端口,即可 ``` **選擇下載站點** 不同的鏡像存放了不同的包,為了獲得最快的下載速度,我們可以添加網易開源鏡像`http://mirrors.163.com/cygwin/`或者 阿里云鏡像`http://mirrors.aliyun.com/cygwin/` ![](https://img.kancloud.cn/53/88/5388cbe33030b3bc929c7ac22bae102b_984x648.png) **開始自動搜索** ![](https://img.kancloud.cn/45/70/4570fe9877badee7b71a9106b8c4726f_863x627.png) **選擇需要下載安裝的組件包** 這一步比較重要,為了之后更好的使用該軟件,建議自己在這里的時候就選好需要使用的組件,或者說支持的命令。 最核心的,記住一定要安裝Devel這個部分的模塊,其中包含了各種開發所用到的工具或模塊。 ***下面推薦推幾個組件*** * fish:一個shell,具有良好的交互提示,強烈建議安裝,后面的操作也和其相關 * lynx:命令安裝組件的必須工具,強烈推薦安裝此項,方便之后擴展命令 * 其他的自選,比如 gcc,curl,python,tclsh等。學習FPGA,建議安裝tclsh **組件可以在search框輸入后搜索,然后選中組件,在new列雙擊,當看到版本號后,安裝就會將此組件安裝上。** ![](https://img.kancloud.cn/c2/a3/c2a306141ee14dac3670cb959fc8f4d0_836x545.png) **確認并開始安裝** ![](https://img.kancloud.cn/26/c2/26c22d4bcdf37609f73942af539a4c5f_835x553.png) **安裝好之后,將cygwin安裝路徑下的bin目錄添加到環境變量,方便使用** **為了讓我們更舒服的使用,我們先把默認的shell設為fish,當然,若果沒安裝fish就算了** 當我們沒配置fish shell,使用默認的shell時我們打開`cygwin`的終端是這樣的 ![](https://img.kancloud.cn/89/76/8976ad6a0fc7525a859f6219111f2d1f_650x241.png) 在終端輸入以下命令后下次重啟就可以了。 ``` echo "fish" >> /etc/profile ``` 當然此時要直接切換到fish可以在終端直接輸入`fish`,切換過來就是這樣的了: ![](https://img.kancloud.cn/7d/e0/7de0e36d69f60e149761e61d1e185b9d_1143x512.png) ## step2:安裝verilog小巧的仿真工具-iverilog 下載鏈接:[windows版本iverilog](http://bleyer.org/icarus/) ![](https://img.kancloud.cn/fa/8e/fa8e8d245cdb68b7cc76fa8946800a5d_963x633.png) 下載后直接安裝,當然為了之后使用方便強烈建議安裝好將安裝路徑下的`bin`目錄和安裝目錄下的`gtkwave/bin`目錄加入環境變量。 ## step3:主要工具準備完畢,在隨意來個編輯器 編輯器在這里推薦使用`vscode`,后面的說明也都會基于這個編輯器。 下載鏈接:[vscode官網](https://code.visualstudio.com/) 注意,記住你的安裝路徑, ![](https://img.kancloud.cn/28/79/28792c4a1370c1a1525f1a446ad82411_1081x648.png) 我們打開他,同樣為了方便使用,在這里先對其進行簡單的配置: **首先安裝幾個必要的插件** ![](https://img.kancloud.cn/9d/3e/9d3e8b27e5124e62a34ad591d7917da8_697x418.png) 在這個里面搜索,為了支持中文,你可以搜索`chinese`,進行安裝,之后又就是中文顯示了。其他的插件可以暫時不用安裝,之后遇到相應的文件后,軟件會自動推薦你安裝,我安裝的插件如下: ![](https://img.kancloud.cn/78/95/7895cb2536cadf2227b0b4eb9950745d_425x1071.png) **關鍵步驟** ![](https://img.kancloud.cn/13/f1/13f1b9664807314f500a0b889e207a2d_785x815.png) 在搜索框搜索`term` ![](https://img.kancloud.cn/50/cc/50cced520fde49f539afb85ed2889fc3_1465x996.png) 然后配置一下: ![](https://img.kancloud.cn/20/5b/205bc3341a5dab4ca697f0a7a98ff388_1391x645.png) 主要就是這幾個,大家最好把這幾項先配置好,省的之后一項一項配置。 ``` { "terminal.integrated.shell.windows": "D:\\cygwin64\\bin\\fish.exe", "files.autoSave": "onFocusChange", "files.autoGuessEncoding": true, "editor.mouseWheelZoom": true } ``` > # 下載mini-mcu 下載地址:[mini-mcu](https://gitee.com/yuan_hp/mini-mcu) ![](https://img.kancloud.cn/f6/4d/f64d59df7dc7b1cb83cf75727867a189_1286x435.png) 如果你安裝cygwin時也安裝了git,那么在cygwin的終端中可以使用: ``` git clone https://gitee.com/yuan_hp/mini-mcu.git ``` 直接克隆。 然后我們使用`vscode`打開我們`mini-mcu`的文件夾,并在打開vscode的終端。 ![](https://img.kancloud.cn/97/e8/97e807fe802f534a1c9c7d4df3e7262f_1724x1075.png) 為了感受一下之后開發的方便,在終端中輸入以下命令: ![](https://img.kancloud.cn/e1/46/e146276fd2093c36b91ae99e035cb21a_1745x1018.png) 該命令行會直接編譯項目中`software`一級目錄下的`.psm`文件,也就是我們的匯編代碼文件,并生成對用的`rom.v`文件,同時裁剪`mini-mcu`,命令`./run`將會調用`iverilog`仿真項目并用`gtkwave`代開仿真的波形圖 ![](https://img.kancloud.cn/7b/9f/7b9fe0bb4c274d3f5959e4f55e35a9f3_1974x1080.png) **特別注意:**當你想開發新的功能時,你可以先不關閉gtkwave,修改`software`下的代碼后,執行以下命令 ![](https://img.kancloud.cn/54/7c/547c1c4e94ac38c5f3ac905393ec15c5_638x43.png) 刷新并行文件的數據,然后在gtkwave重新加載數據: ![](https://img.kancloud.cn/fc/5f/fc5f9a463ec82fd0aeb1a6d4b52b2805_559x516.png) > # 項目文件結構 ``` ├── head.v 用于裁剪mini-mcu的宏文件 ├── images 存放著圖片 ├── mcu.v mini-mcu源碼 ├── README.md ├── rom.v 編譯匯編自動成成的程序存儲器 ├── run 項目控制腳本 ├── run.sh ├── sim 生成的仿真文件 │ ├── wave │ └── wave.lxt2 ├── software 編寫的匯編代碼 │ ├── test.psm 腳本會編譯的代碼 │ ├── 第一個例子 │ │ └── start.psm │ ├── 簡單按鍵檢測 │ │ └── keycheck.psm │ ├── 流水燈程序 │ │ └── led_water.psm │ └── 數碼管計數 │ └── seg_counter.psm ├── step_fpga 小腳丫fpga的歷程項目,執行 ./run -g 會將文件拷貝到這個目錄下 ├── tb.v 仿真testbech文件 ├── tmp 執行腳本時生成的臨時文件夾 │ ├── kcpsm6.exe │ ├── KCPSM6_session_log.txt │ ├── ROM_form.v │ ├── test.fmt │ ├── test.hex │ ├── test.log │ ├── test.psm │ └── test.v ├── tools 仿真一些工具和腳本 │ ├── bin │ │ ├── compile │ │ ├── hex2rom │ │ └── msim │ └── kcpsm │ ├── kcpsm6.exe │ └── ROM_form.v ├── upCloud └── window.v 專門用來查看mcu內部變量的模塊 ``` > # 已經支持的指令 * LOAD * JUMP * JUMP C * JUMP NC * JUMP Z * JUMP NZ * CALL C * CALL NC * CALL Z * CALL NZ * CALL * RETURN * RETURN C * RETURN NC * RETURN Z * RETURN NZ * AND * OR * XOR * INPUT * OUTPUT * ADD * ADDCY * SUB * SYBCY * COMPARE * TEST * SL0 * SL1 * RL * RR * SR0 * SR1 * SLA * SRA * ENABLE INTERRUPT * DISABEL INTERRUPT * RETURNI * JUMP @(sX,sY) * CALL @(sX,sY) ![](https://img.kancloud.cn/41/74/41744e4a3f75d2eaee430118f496b558_1226x762.png) > # 開發你的項目 ## step1:編寫代碼 腳本只會自動搜索`software`一級目錄下的`.psm`文件! ``` start: ????LOAD?sA?,?23;?加載寄存器A的值為?0x23 ADDsA,02;寄存區A的值加上?0x02 ``` ## step2:編譯 執行命令`./run -c`編譯文件 ![](https://img.kancloud.cn/fc/e5/fce523cb3f341206aabe06383371a3e2_987x792.png) ## step3:仿真verilog項目 執行命令:`./run` ![](https://img.kancloud.cn/ef/7c/ef7cd4cf1685a94d136227d55538b4f6_1044x580.png) ## step4:板上驗證 拷貝項目目錄下的`mcu.v, rom.v , head.v`到實際的FPGA實際項目的目錄下,進行,并編寫項目的頂層文件:參考如下: ``` module top ( input clk_in, //輸入系統12MHz時鐘 //4bit撥碼開關輸入 input [3:0] sw, input [3:0] key, //按鍵輸入 //數碼管 output [8:0] seg_led_1, output [8:0] seg_led_2, //rgb output reg[2:0]rgb, //led output led1, output led2, output led3, output led4, output led5, output led6, output led7, output led8 ); wire clk ,clko,rst; reg [7:0] out; assign {led8,led7,led6,led5,led4,led3,led2,led1} = out; assign clk = clk_in; reg rst_n_in; //復位信號 reg [17:0]cnt ; always @(posedge clk) begin if(cnt>=18'h3ffff)begin rst_n_in <= 1'b1; end else begin cnt <= cnt +1; rst_n_in <= 0; end end /* divide #( .N(1) ) u1 ( .clk(clko), .rst_n(rst_n_in), .clkout(clk) ); */ //----------- mini-mcu 相關------------ wire [11:0]address; wire [17:0] instruction; wire bram_enable, read_strobe, write_strobe; reg [7:0] in_port; wire [7:0] port_id, out_port; //----------- 數碼管 相關------------ reg[3:0] seg_data_1, seg_data_2; //輸出引腳 always @(posedge clk )begin if(write_strobe)begin case(port_id) 8'h00:{seg_data_1,seg_data_2} <= out_port;//bcd編碼的2個數碼管 8'h01:out <= out_port; //LED控制 8'h02:rgb <= out_port[2:0]; //rgb default:out <=out; endcase end else out <= out; end //輸入引腳 always@(*)begin if(read_strobe) begin case(port_id) 8'h00: in_port = {key[3:0],sw[3:0]}; //按鍵 4bit撥碼開關輸入 endcase end end /********************************** * 例化mini-mcu **********************************/ mcu mcu( .clk(clk), //系統時鐘 .rst_n( rst_n_in), //復位 0 --> 復位 .address( address), //程序取址地址 .instruction( instruction), //指令輸入 .bram_enable( bram_enable), //程序rom使能 1-->使能 .in_port( in_port), //輸入口 .read_strobe( read_strobe), //輸入口使能 .port_id( port_id), //io口地址 .out_port( out_port), //輸出口 .write_strobe( write_strobe) //輸出口寫使能 ); rom rom( .clk( clk), .address( address), //程序取址地址 .instruction( instruction), //指令輸入 .enable( bram_enable) //程序rom使能 1-->使能 ); /********************************** *數碼管顯示 是bcd碼 **********************************/ seg_display seg_display( .seg_data_1(seg_data_1), .seg_data_2(seg_data_2), .seg_led_1(seg_led_1), .seg_led_2(seg_led_2) ); endmodule ``` > # 幾個實例 ## 流水燈 ``` ;系統時鐘為倍頻到120MHz ;目標硬件為 小腳丫FPGA step-maxo2-c,這個型號是U盤模式,流文件會下載到mcu,每次上電由mcu配置FPGA ;輸入 constant sw_port,00 ;定義按鍵四段撥碼開關 【按鍵 : 開關 】 ;輸出 constant seg_port,00 ;定義數碼管地址 constant led_port,01 ;定義led_port為常量01 constant rgb_port,02 ; rgb燈 start: load sA,FE ; led等控制 load sB,12 ; 初始化數碼管顯示 12 load sC,00000111'b ; ' rgb 滅 output sC,rgb_port ;rgb不量 input sD,sw_port ; 讀一次io口 output sB, seg_port ;數碼管顯示 loop: output sA, led_port ;流水燈實現 RL sA ;循環左移 call delay_500ms jump loop ;循環 delay_500ms: LOAD s2, 09 ; 500000us / (1/1.2us) --> 計數次數 LOAD s1, 27 LOAD s0, c0 jump software_delay software_delay: LOAD s0, s0 ;pad loop to make it 10 clock cycles (5 instructions), if clk 12MHz --> 1/1.2 us SUB s0, 01 SUBCY s1, 00 SUBCY s2, 00 JUMP NZ, software_delay RETURN ``` ## 數碼管計數器 ``` ;系統時鐘為12MHz ;目標硬件為 小腳丫FPGA step-maxo2-c,這個型號是U盤模式,流文件會下載到mcu,每次上電由mcu配置FPGA ;輸入 constant sw_port,00 ;定義按鍵四段撥碼開關 【按鍵 : 開關 】 ;輸出 constant seg_port,00 ;定義數碼管地址 constant led_port,01 ;定義led_port為常量01 constant rgb_port,02 ; rgb燈 start: load sA,FF ; led等控制 output sA,led_port load sB,00 ; 初始化數碼管顯示 load sC,00000111'b ; ' rgb 滅 output sC,rgb_port ;rgb不量 input sD,sw_port ; 讀一次io口 loop: output sB, seg_port ADD sB,01 load sE,sB ; SL0 sE SL0 sE SL0 sE SL0 sE COMPARE sE,A0 CALL Z,carry ;越界進位 LOAD sE,sB SR0 sE SR0 sE SR0 sE SR0 sE COMPARE sE,0A CALL Z,clear ;滿了清零 call delay_500ms jump loop ;循環 carry: ;bcd碼表示的低四位已經滿了,整體加6 ADD sB,06 RETURN clear: ;到了99后,下一步歸零 LOAD sB,00 RETURN delay_500ms: LOAD s2, 09 ; 500000us / (1/1.2us) --> 計數次數 LOAD s1, 27 LOAD s0, c0 jump software_delay software_delay: LOAD s0, s0 ;pad loop to make it 10 clock cycles (5 instructions), if clk 12MHz --> 1/1.2 us SUB s0, 01 SUBCY s1, 00 SUBCY s2, 00 JUMP NZ, software_delay RETURN ``` ## 8位乘法器 ``` ;系統時鐘為12MHz ;目標硬件為 小腳丫FPGA step-maxo2-c,這個型號是U盤模式,流文件會下載到mcu,每次上電由mcu配置FPGA start: load s0 , 0a ; 加載寄存器0的值 load s1,08 ; 寄存器1的值 call mult ; s0 * s1 => s2 wait: jump wait ; 8位乘法 計算 s0 * s1 ==> s2 mult : load s2,00 mult_loop: add s2,s0 sub s1,01 jump nz,mult_loop return ;16位乘法 [s1,s0] * [s3,s2] => [s5,s4] mult16 : load s5,00 load s4,00 mult16_loop: add s4,s2 addcy s5,s3 sub s0,01 subcy s1,00 jump nz,mult16_loop return ``` > # 個人實驗開發板 我做實驗的開發板為小腳丫FPGA,型號為`STEM-MX02-C`,這是U盤模式的,芯片為Lattice的,項目下已經有對應的工程,就是`step_fpga`,如果你的開發板也是這個,同時也安了diamond,也將diamond的可執行路徑加入了環境變量,那么可以執行命令`./run -g`,就會編譯代碼,拷貝文件,綜合工程,下載到開發板了,你可能需要修改的是在`step_fpga`下的`run.tcl`腳本的最后一行。 ![](https://img.kancloud.cn/90/ce/90ce6e938196d2cf2122c92d8c97b2c3_1185x555.png) `pnmainc`是diamond工具的tcl命令工具! > # 總結 個人水平有限,中斷部分過段時間在添加,對于實現簡單傳感器的采集,已經足夠用了,導師抓得緊,牙縫里擠出的時間寫的這個小項目,收獲了很多,現在這個項目只是模型,之后會逐步完善!
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看