# 軟硬體協同設計報告 # HW1 Vivado usage (4-bit full adder ) 學生: 陳奕霖 M1125143 | 指導老師:林宏益教授 >[color=#6038af]實驗目的: 在VScode使用verilog撰寫一個4-bits全加器,並輸出v檔在Vivado模擬schematic和在gtkwave模擬波形圖。 >[color=#6038af]實驗原理: >全加法器: 將被加數、加數與前一個低位元相加 > >四位元加法器最右不會有溢位因此只需要使用半加法器 > > >![](https://hackmd.io/_uploads/HyioUKFep.png =75%x) > >[color=#6038af]實驗材料: PC,VScode,Vivado,gtkwave --- >[color=#6038af]實驗步驟:首先在 VScode上撰寫 4-bit adder verilog ```verilog= // 1位元加法器模組 module add1 ( a, // 被加數 b, // 加數 cin, // 進位輸入 cout, // 進位輸出 sum // 總和 ); input a, b, cin; output cout, sum; assign {cout, sum} = a + b + cin; endmodule // 4位元加法器模組 module add4 ( a, // 被加數 b, // 加數 cin, // 進位輸入 cout, // 進位輸出 sum ); input [3:0] a, b; input cin; output cout; output [3:0] sum; wire c0, c1, c2; // 中間進位信號 // 實例化4個1位元加法器 add1 add1_0 (.a(a[0]), .b(b[0]), .cin(cin), .cout(c0), .sum(sum[0])); add1 add1_1 (.a(a[1]), .b(b[1]), .cin(c0), .cout(c1), .sum(sum[1])); add1 add1_2 (.a(a[2]), .b(b[2]), .cin(c1), .cout(c2), .sum(sum[2])); add1 add1_3 (.a(a[3]), .b(b[3]), .cin(c2), .cout(cout), .sum(sum[3])); endmodule ``` >[color=#6038af]依自己測試需求撰寫testbench測試,接著用makefile合出 .vcp檔模擬波形 >![](https://hackmd.io/_uploads/SyzOcKYgT.png =40%x) >[color=#6038af]在gtkwave中模擬波形 >![](https://hackmd.io/_uploads/S1jgTKtga.png =70%x) >[color=#6038af]最後把檔案add進Vivado跑Schematic,以下為Schematic圖 ![](https://hackmd.io/_uploads/BkAqAtKea.png) --- >[color=#6038af]實驗討論: >這次遇到了很奇怪的麻煩,當我加入test.v檔後不知為何會一直同步跑到simulation source底下,導致我加入test_tb跑behavior simulation時波形怪怪的,在想是不是include module導致,所以我只好使用gtkwave來跑波形圖。 >[color=#6038af]實驗心得: 做了這份作業後我學到了很多我原本不知道的東西,例如`include與Topmodule的觀念,testbench的撰寫。完整操作過一遍也加深了對操作流程的印象,但完成後也使我心裡有點恐懼,因為要能對此瞭若指掌還得經過一次次的失敗和嘗試才能出師,不過我相信日後積累的失敗必定能使我有顯著的成長。 參考資料: https://www.youtube.com/watch?v=kyFW1UuknRE&t=345s&ab_channel=.DeltaMOOCx https://www.youtube.com/watch?v=f-MyEpbChGw&ab_channel=%E5%90%B3%E9%A0%86%E5%BE%B7 https://www.youtube.com/watch?v=r-XmmhPIR14&list=PLI6pJZaOCtF1-GOBBFwGtAYclboJfTFws&index=23&ab_channel=.DeltaMOOCx # HW2 BCD to Decimal Decode >[color=#6038af]實驗目的: 編寫BCD解碼器透過testbench驗證正確性,並在Vivado模擬schematic觀察與RTL差別與分析功率及面積報告 > >[color=#6038af]實驗材料: PC,VScode,Vivado,gtkwave --- >[color=#6038af]實驗步驟:首先先編寫BCD解碼器,加入Preset與Reset按鈕 ## 1.RTL ```verilog= module BCD2DD( bcd, dec, Reset_n, Preset ); input [3:0] bcd; input Reset_n,Preset; output [9:0] dec; reg [9:0] dec; always @(bcd or Reset_n or Preset) begin if(Preset == 1) begin dec = 10'b0000001111; end else if(Reset_n == 0 ) case (bcd) 4'bxxxx : dec = 10'b0000000000; endcase else case (bcd) 4'b0000 : dec = 10'b1111111110; 4'b0001 : dec = 10'b1111111101; 4'b0010 : dec = 10'b1111111011; 4'b0011 : dec = 10'b1111110111; 4'b0100 : dec = 10'b1111101111; 4'b0101 : dec = 10'b1111011111; 4'b0110 : dec = 10'b1110111111; 4'b0111 : dec = 10'b1101111111; 4'b1000 : dec = 10'b1011111111; 4'b1001 : dec = 10'b0111111111; 4'b1010 : dec = 10'b1111111111; 4'b1011 : dec = 10'b1111111111; 4'b1100 : dec = 10'b1111111111; 4'b1101 : dec = 10'b1111111111; 4'b1110 : dec = 10'b1111111111; 4'b1111 : dec = 10'b1111111111; endcase end endmodule ``` ## 2.TestBench ````verilog= module BCD2DD_tb; reg [3:0] bcd; wire [9:0] dec; reg Reset_n, Preset; integer i; BCD2DD uut ( .bcd(bcd), .dec(dec), .Reset_n(Reset_n), .Preset(Preset) ); initial begin Reset_n = 1; #50; Preset = 0; $dumpfile("BCD2DD.vcd"); $dumpvars(0,BCD2DD_tb); $monitor ("Reset_n = %b Preset = %b bcd = %b dec = %b", Reset_n , Preset , bcd , dec); for( i=0 ; i<16 ; i=i+1 ) begin bcd = i; #50; end Reset_n = 0; bcd = 4'bxxx; #50; Preset = 1; #50; end endmodule ```` <br/> ## 3.TestBench結果 ![](https://hackmd.io/_uploads/S12qK2RxT.png) ## 4. 模擬波形 ![](https://hackmd.io/_uploads/SJfYdMNW6.png) * 當reset_n=0時,輸出歸0 * 當preset=1時,輸出10'b0000001111 ## 5.功率分析 ![](https://hackmd.io/_uploads/S1SM7T0eT.png) >[color=#6038af] 從這次的功率分析看到 I/O、Logic、Signals占比分別是91% : 5% : 4%,I/O占了絕大功耗,推測可能跟輸出有10bit有關。 ## 6.面積報告 ![](https://hackmd.io/_uploads/Bklx760l6.png) >[color=#6038af]面積占用比很低,推測使用到此FPGA的logic很少。 ## 7.Schematic ![](https://hackmd.io/_uploads/rysoQp0xT.png) >[color=#6038af]Schematic相較上一個實驗些許複雜,多了許多電子元件需要一一去理解其功能,需花費時間理解,依我目前功力不能確定實質是否正確,但這是我未來應該努力去開發學習的地方。 --- >[color=#6038af]實驗心得: 這次實驗在verilog語法上使用到if else的應用,testbench放入if else對在編寫testbench時增加了編寫效率,日後會大量使用,另外也嘗試使用更簡短的方式編寫但還是有出錯的地方未找到,關於分析的部分要多多累積經驗才能分析出有用的結論,這是現在我還未能掌握到的很重要的一環。 ## FPGA燒錄 ### Preset = 1 ![IMG_0922.jpeg](https://hackmd.io/_uploads/HyYGBvD7a.jpg =70%x) ### Reset = 0 ![IMG_0923.jpeg](https://hackmd.io/_uploads/BJqDHwPm6.jpg =70%x) ### 影片連結 https://youtube.com/shorts/CM5NgQ9XwXU?feature=share # HW3 & 4 Decimal to 7-Seg Display Lab >[color=#6038af]實驗目的 : >編寫七段顯示器RTL並驗證正確性,並在Vivado合成schematic,觀察與RTL差異與分析功率 >[color=#6038af]實驗材料: PC,VScode,Vivado,工作站 --- ## 實驗原理 ![](https://hackmd.io/_uploads/S1MxmIRM6.png) **共陽極的接法**: 低電位發光,高電位熄滅,共陽極接法的LED,是將多個直接點亮接法的LED的陽極接再一起,共陽極接法的點亮方式和直接點亮接法原理相同,只要在LED的雙端接上正確的電壓就可點亮 ![](https://hackmd.io/_uploads/rys6Sw0za.png =70%x) ## RTL ```verilog= module seg( in, seg, Reset ); input [3:0] in; input Reset; output [7:0] seg; reg [7:0] seg; always @(in or Reset) begin if(Reset == 0) begin seg = 8'b1001_0001; end else case (in) 4'b0000 : seg = 8'b0000_0011; 4'b0001 : seg = 8'b1001_1111; 4'b0010 : seg = 8'b0010_0101; 4'b0011 : seg = 8'b0000_1101; 4'b0100 : seg = 8'b1001_1001; 4'b0101 : seg = 8'b0100_1001; 4'b0110 : seg = 8'b0100_0001; 4'b0111 : seg = 8'b0100_0001; 4'b1000 : seg = 8'b0001_1111; 4'b1001 : seg = 8'b0000_0001; 4'b1010 : seg = 8'b0000_1001; 4'b1011 : seg = 8'b0001_0001; 4'b1100 : seg = 8'b1100_0001; 4'b1101 : seg = 8'b1000_0101; 4'b1110 : seg = 8'b0110_0001; 4'b1111 : seg = 8'b0111_0001; endcase end endmodule ``` ## TestBench ```verilog= module t_seg; reg [3:0] in; wire [7:0] seg; reg Reset; integer i; seg instantiate ( .in(in), .seg(seg), .Reset(Reset) ); initial begin Reset = 1; $dumpfile("seg.vcd"); $dumpvars(0,t_seg); $monitor ("Reset = %b in = %b seg = %b", Reset , in , seg); for( i=0 ; i<16 ; i=i+1 ) begin in = i; #50; end #50; Reset = 0; #50; end endmodule ``` ## TestBench結果 ![](https://hackmd.io/_uploads/Skqt6Uvf6.png) ## 模擬波形 ![](https://hackmd.io/_uploads/HyvPoIvz6.png) ## 工作站波行模擬 ![](https://hackmd.io/_uploads/B1Nb3Uvza.png =300%x) ![](https://hackmd.io/_uploads/HJ3_TSCza.png) <br/> ## 功率分析 ![](https://hackmd.io/_uploads/ryB2NIAGp.png) ## 面積使用率 ![](https://hackmd.io/_uploads/BybKoPRf6.png) ## Schematic ![](https://hackmd.io/_uploads/Bkqkn8Df6.png) ## 實驗心得 >[color=#6038af] 這次的實驗思路與上次作業BCD解碼器相似,因此使用switch case完成,也把Power和上次實驗做了比較,發現Power用量較低,可能跟這次沒有Preset開關有關,LUT相比之下也因此少了3個。 >工作站VCS和Verdi的初步使用沒有一開始想像的那麼複雜,另外比較要注意的是工作站波形模擬尚未找到好的顯示方式。 ## FPGA燒錄 ### Reset = H ![IMG_1099.JPEG](https://hackmd.io/_uploads/BJXIODPQT.jpg =70%x) ### 0000 = 0 ![IMG_1094.JPEG](https://hackmd.io/_uploads/H1VB9wDmT.jpg =70%x) ### 0001 = 1 ![IMG_1095.JPEG](https://hackmd.io/_uploads/HyQ3tDD7p.jpg =70%x) ### 0010 = 2 ![IMG_1096.JPEG](https://hackmd.io/_uploads/ByomovDma.jpg =70%x) ### 0011 = 3 ![IMG_1100.JPEG](https://hackmd.io/_uploads/BJ5E2wD76.jpg =70%x) ### 1111 = F ![IMG_1102.JPEG](https://hackmd.io/_uploads/rJ9btwP7p.jpg =70%x) # HW5 Improve code coverage of your Design >[color=#6038af]實驗目的 : 提升 (1) Line (2) FSM (3) Condition (4) Branch 的coverage覆蓋率 >[color=#6038af]實驗需求: 工作站 --- ## 實驗原理 行覆蓋率(Line Coverage):評估程式中每一行是否已經被testbench執行過。 條件覆蓋率(Condition Coverage):用來確保每個條件語句(如if語句)的所有可能結果都被測試過。 有限狀態機覆蓋率(Finite State Machine Coverage):確保有限狀態機的所有可能狀態和狀態轉換都被測試過。 分支覆蓋率(Branch Coverage):用來確保每個程式碼分支(如if/else語句)和邏輯分支都被測試過。 實驗: 試著一一提升覆蓋率 ## 初始覆蓋率 ![螢幕擷取畫面 2023-11-17 原版](https://hackmd.io/_uploads/SJn3q2d4a.png) --- ## Line coverage ![螢幕擷取畫面 2023-11-20 190336](https://hackmd.io/_uploads/rJTM62OEp.png) 根據紅框這行default沒有被執行到,因此我將他暫時移除,移除後可以發現Line coverage因此提升到100% ![螢幕擷取畫面 2023-11-17 line coverage提升](https://hackmd.io/_uploads/Bke2p3dN6.png) ## Branch coverage 根據系統紅框提示,這行條件敘述應該有沒有執行到的地方。我將?:條件敘述改為 if else實驗,Branch coverage稍微提升 ![螢幕擷取畫面 2023-11-20 190913](https://hackmd.io/_uploads/S1Vw03dNT.png) ![螢幕擷取畫面 2023-11-20 191302](https://hackmd.io/_uploads/B1pS1ad4T.png) ![螢幕擷取畫面 2023-11-17 branch coverage提升](https://hackmd.io/_uploads/SyOAJadN6.png) ## FSM coverage ### Test 1 增加一個狀態 S2 (2'd3) 補齊2bit的4種狀態(00,01,10,11),但是FSM只提升到了83.3%。依然發現一樣的問題,S0沒有轉換到IDLE,所以轉為修改Test_bench。 ![螢幕擷取畫面 2023-11-20 214205](https://hackmd.io/_uploads/S1UDG1FVp.png) ### Test 2 ![螢幕擷取畫面 2023-11-21 114041](https://hackmd.io/_uploads/rJuQqjtVT.png) 根據波形圖(200ns、400ns)可以發現S0在過程中並沒有觸發到inp1 =0 到IDLE狀態。 修改Testbench,原本延遲為100ns,把延遲時間縮小到可以成功觸發S0 -> IDLE。根據clk正緣觸發週期,inp1=0延續時間必須大於5ns ![螢幕擷取畫面 2023-11-21 152425](https://hackmd.io/_uploads/H1qYxk5Vp.png) 結果:經過Testbench 延遲時間修正到>5ns,<15ns(下一次的正緣觸發之前) 可以讓S0成功轉換到IDLE進而將FSM Coverage提升到100% ![螢幕擷取畫面 2023-11-21 162235](https://hackmd.io/_uploads/rJp1F1cVa.png) ## 實驗心得 提升Coverage的覆蓋率得對自己正在執行的程式聊若指掌,不然得付出大量的時間,程式所有的細節都會影響的機會,這次的作業FSM覆蓋率的部分經過非常多次的嘗試修改,最後確認是S0少跑一個狀態導致。 # HW6 7-Seg Display Controlled by UART >[color=#6038af]實驗目的 : >編寫RTL程式燒錄到FPGA面版,使用UART接收PC端TX訊號並將收到的訊號顯示在七段顯示器 >[color=#6038af]實驗材料: PC,Vivado,工作站 ## UART簡介 :::info UART發送端與接收端並不是由共同的時鐘信號來持續對齊,而是透過事先決定好頻率與開始、停止信號來判斷何時讀取資料。 ![螢幕擷取畫面 2023-12-06 114524](https://hackmd.io/_uploads/HkYACwaS6.png) 封包由一個Start bit + 8Bits data + 1Stop bit(奇偶較驗位),共10bits組成。 ![螢幕擷取畫面 2023-12-06 112520](https://hackmd.io/_uploads/rky0CDTBT.png) 開始位元為高電位轉為第一個的低電位,接收完個8bits完至奇偶較驗位(高電位) ::: ## 實作影片紀錄 :::info https://youtu.be/Dy2nt7xT2bo ::: ## RTL ### UART架構(rx) ![螢幕擷取畫面 2023-12-09 113533](https://hackmd.io/_uploads/rJ_DbPW8p.png =70%x) #### Top module ````VERILOG= `timescale 1ns / 1ps module rx_top( input clk, input rst, input rx_pin_in, output [7:0] seg7 ); wire [7:0] rx_data; wire rx_band_sig; wire clk_bps; rx_band_gen rx_band_gen( .clk( clk ), .rst( rst ), .band_sig( rx_band_sig ), .clk_bps( clk_bps ) ); H2L_detect rx_in_detect( .clk( clk ), .rst( rst ), .pin_in( rx_pin_in ), .sig_H2L( rx_pin_H2L ) ); rx_ctl rx_ctl( .clk( clk ), .rst( rst ), .rx_pin_in( rx_pin_in ), .rx_band_sig( rx_band_sig ), .rx_clk_bps( clk_bps ), .rx_data( rx_data ), .rx_done_sig( rx_done_sig ) ); ASCII27 ASCII27( .rst( rx_done_sig ), .ascii( rx_data ), //rx_data訊號->ASCII .seg7(seg7) ); endmodule ```` #### (H2L_detect):偵測start訊號 ````VERILOG= `timescale 1ns / 1ps module H2L_detect( input clk, input rst, input pin_in, output sig_H2L ); reg pin_pre; assign sig_H2L = !pin_in & pin_pre; always @( posedge clk or posedge rst ) if( rst ) pin_pre <= 1'b0; else pin_pre <= pin_in; endmodule ```` #### rx_ctl 狀態機出發接收動作 ````VERILOG= `timescale 1ns / 1ps module rx_ctl( input clk, input rst, input rx_pin_in, input rx_pin_H2L, output reg rx_band_sig, input rx_clk_bps, output reg[7:0] rx_data, output reg rx_done_sig ) ; localparam [3:0] IDLE = 4'd0, BEGIN = 4'd1, DATA0 = 4'd2, DATA1 = 4'd3, DATA2 = 4'd4, DATA3 = 4'd5, DATA4 = 4'd6, DATA5 = 4'd7, DATA6 = 4'd8, DATA7 = 4'd9, END = 4'd10 , BFREE = 4'd11; //選擇使用4位元表示狀態是為了確保有足夠的位元數來表示所有可能的狀態(獨一無二定義數) reg [3:0] pos; always@( posedge clk or posedge rst ) if( rst ) begin rx_band_sig <= 1'b0; rx_data <= 8'd0; pos <= IDLE; rx_done_sig <= 1'b0; end else case( pos ) IDLE: if( rx_pin_H2L) begin rx_band_sig <= 1'b1; pos <= pos + 1'b1; rx_data <= 8'd0; end if( rx_clk_bps) begin if( rx_pin_in == 1'b0 ) begin pos <= pos + 1'b1; end else begin rx_band_sig <= 1'b0; pos <= IDLE; end end DATA0,DATA1,DATA2,DATA3,DATA4,DATA5,DATA6,DATA7 //接續儲存 if( rx_clk_bps) begin rx_data[ pos - DATA0 ] <= rx_pin_in; pos <= pos + 1'b1; end END: if( rx_clk_bps) begin rx_done_sig <= 1'b1; pos <= pos + 1'b1; rx_band_sig <= 1'b0; end BFREE: begin rx_done_sig <= 1'b0; pos <= IDLE; end endcase endmodule ```` #### rx_band_gen 產生9600bps 接收資料 ````VERILOG= `timescale 1ns / 1ps module rx_band_gen( input clk, input rst, input band_sig, output reg clk_bps ); parameter SYS_RATE = 125000000; parameter BAND_RATE = 9600; parameter CNT_BAND = SYS_RATE / BAND_RATE; parameter HALF_CNT_BAND = CNT_BAND / 2; reg [13:0] cnt_bps; always @( posedge clk or posedge rst ) if( rst ) begin cnt_bps <= HALF_CNT_BAND; clk_bps <= 1'b0; end else if( !band_sig ) begin cnt_bps <= HALF_CNT_BAND; clk_bps <= 1'b0; end else if( cnt_bps == CNT_BAND ) begin cnt_bps <= 14'd0; clk_bps <= 1'b1; end else begin cnt_bps <= cnt_bps + 1'b1; clk_bps <= 1'b0; end endmodule ```` #### ASCII27 ````VERILOG= module ASCII27 ( rst, Ascii, seg7 ); input rst; input [7:0] Ascii; reg [7:0] seg7; output [7:0] seg7_out; always@( posedge rst ) begin case (Ascii) //Spyglass requires nonblocking 8'b0011_0000 : seg7 <=8'b0000_0011; 8'b0011_0001 : seg7 <=8'b1001_1111; 8'b0011_0010 : seg7 <=8'b0010_0101; 8'b0011_0011 : seg7 <=8'b0000_1101; 8'b0011_0100 : seg7 <=8'b1001_1001; 8'b0011_0101 : seg7 <=8'b0100_1001; 8'b0011_0110 : seg7 <=8'b0100_0001; 8'b0011_0111 : seg7 <=8'b0001_1111; 8'b0011_1000 : seg7 <=8'b0000_0001; 8'b0011_1001 : seg7 <=8'b0000_1001; 8'b0100_0001 : seg7 <=8'b0001_0001; 8'b0100_0010 : seg7 <=8'b1100_0001; 8'b0100_0011 : seg7 <=8'b1110_0101; 8'b0100_0100 : seg7 <=8'b1000_0101; 8'b0100_0101 : seg7 <=8'b0110_0001; 8'b0100_0110 : seg7 <=8'b0111_0001; default : seg7 <=8'b0110_0001; endcase assign seg7_out=seg7; end endmodule ```` ## TestBench ````verilog= module rx_tb(); reg clk; reg rst; reg uart_rx; wire [7:0] seg7; rx_top u_rx_top( .clk(clk), .rst(rst), .rx_pin_in(uart_rx), .seg7(seg7) ); initial begin clk=0; //INIT rst=1; //觸發start posedge 開始接收訊號 rst=0; //復位 uart_rx=1; //(確保高電位) //Start bit #130208 uart_rx = 0; //Ascii test #130208 uart_rx = 1; #130208 uart_rx = 0; #130208 uart_rx = 0; #130208 uart_rx = 0; #130208 uart_rx = 0; #130208 uart_rx = 0; #130208 uart_rx = 0; #130208 uart_rx = 0; //Stop bit #130208 uart_rx = 1; #130208 uart_rx = 1; #130208 uart_rx = 1; #130208 uart_rx = 1; end always #10 clk=~clk; endmodule ```` * Teshbench參考參考資料 2。 * 波特率=每秒可傳輸bits的速率,實驗用板子時脈=125MHz,1bit所需傳輸時間125M/9600=130208(ns) ## Simulation :::success ![IMG_0059](https://hackmd.io/_uploads/rkutuvaHT.jpg) 9600(baud/second): 每個訊號間格為1/9600=104µs 經過104µs低電位(Start bit)後開始接收訊號,但由於訊號還不穩定所以會先等54µs後才真正開始儲存來源訊號(per data bit)。 ::: ## Schematic ![螢幕擷取畫面 2023-12-05 133328](https://hackmd.io/_uploads/ByZops3rT.png) ## Coverage :::success ![螢幕擷取畫面 2023-12-07 105608](https://hackmd.io/_uploads/ryRPEhAHa.png) * 開始的Test bench寫法跑coverage覆蓋率很低(TB如上),所以把實驗要求所有情況和default都補上,重跑一遍後覆蓋率有顯著提升。 * Branch coverage: 原本Module rx_ctl部分缺少 else和 default ,因此覆蓋率只有85%左右 拉低了整體覆蓋率。所以加上 default的條件與Coverage on/off提升,並防止line Coverage下降。 * FSM coverage: 由於參考的程式碼沒有跑出FSM coverage,找出原因發現狀態轉換敘述不完整,所以想用Current state ,Next state..去化簡原本的12個狀態,試著嘗試很多次修改程式碼仍然效果不好,所以最後未在Makefile加入執行FSM coverage。(經過Spyglass發現有可能是因為同時含有兩個邏輯敘述導致不會出現FSM Coverage) * Line coverage: 沿用 //coverage on //coverage off屏蔽掉未執行到的程式碼提升了覆蓋率。 ::: ![螢幕擷取畫面 2023-12-07 104530](https://hackmd.io/_uploads/SklD7nCSp.png) ## Lint(SPYGLASS) :::success ![螢幕擷取畫面 2023-12-06 105626](https://hackmd.io/_uploads/rylXOw6rp.png) ### Warnings ![螢幕擷取畫面 2023-12-06 102048](https://hackmd.io/_uploads/SyuQchArT.png) Sequential and Combinational parts of FSM desciption should be seperated : * 時序和組合邏輯部分在同一個Top module 中造成。因為同一個區塊中用了時序(正負緣觸發)和組合邏輯(ascii27)導致,所以盡量不要把這兩個邏輯敘述放在一起,不然會導致程式提高複雜性,進而降低程式的可讀性,在使用Tool上也會增加負擔,得回去重新修改RTL Code. ::: ## 參考資料 https://www.youtube.com/watch?v=IyGwvGzrqp8 https://blog.csdn.net/qq_24287711/article/details/130294198?utm_medium=distribute.pc_relevant.none-task-blog-2 # HW7 人月神話專案管理讀書心得 ## 1.外科手術團隊: 如同人月神話篇章所提,一個項目的完成速度不是由人數來取決,軟件工程的工作之間往往存在一個前後關係,得完成一項才能接著另一項,加進來的人手並不能馬上展開後面的工作,所以透過增加人手來加速開發往往只是一種神話。但作者提出參照外科手術的團隊概念,讓人佩服,彷彿可以輕鬆解決這項難題,像是Steve Jobs所說一個聰明的人可以抵過50個平凡的人,只要多數人圍繞在主治動刀醫生的周邊作為輔助,就可以大大提升項目成功機率。 ## 3.沒有銀彈: 銀彈也就是銀做的子彈,傳說中為了殺死狼人必須使用白銀材質的子彈才行,軟體猶如一般人,但一出了差錯便有可能化身為恐怖的狼人,這個篇章中銀彈代表著能徹地解決問題的方法或技能,希望能一槍將狼人斃命。但是在軟件工程管理中,一定會遇到無法解決的困難,過程中不可能如願一帆風順,作者對此也給出了原因,其一是電腦技術發展速度過於迅速,工程師必須不斷學習新技術與知識,同時也要面對社會需求給軟體帶來的變化,其二,作者提出了複雜性(組織管理,技術)、配合性(規則的差異)、異變性(需求變化)、與隱匿性(語言交流和認知困難)。 最後作者也盡可能改善這些困難造成的困境,第一是採用高階語言以化繁為簡提升開發效率,第二是透過專家系統,專家系統具有推理引擎和知識庫,可以接收資料來推導結果,也利用更上層的人工智慧成為研發助力。