姓名 | 學號 |
---|---|
劉永勝 | F94089032 |
蔡宗瑾 | E14083137 |
李宇洋 | E24099025 |
不同於上次實驗,這次是要以c code控制led燈的亮燈順序。不像verilog有平行處理的概念,c code是序項執行。因此分成以下3個步驟,依序執行,完成這此實作。
Set LED color
設定三個參數,R、G、B,分別代表該顏色的16進為數值。例如紫色的16進制為0x7f_1f_ff
,則分別指定參數 R = 0x7f
、G = 0x1f
、B = 0xff
。
Bright
3'b001
、綠燈表示 3'b010
、藍燈表示 3'b100
。藉由不斷開關R、G、B三個燈的,欺騙人眼的方式實現PWM效果。 (但之後發現用c code的arithmetic operator &
、|
會更好)Change color
題目要求6個顏色的燈要依序閃爍,則使用的個counter,每閃完一個燈號則加一,對此參數取 mod6
,則可再步驟一set color時控制顏色。
此專案為單純讓c code跑在processing system上,並沒有使用到AXI介面資料傳輸,因此沒有考慮sorting電路的寫法。我們採用quick sort演算法,quicksort是一種遞迴式的排序演算法,其pseudo code如下所示:
PARTITION的功能即是將array最右端的值A[r]與array其他值做比較,並且將array分成兩部分,左半部比A[r]小,右半部比A[r]大。
需先輸入要排序的數字總數(key numbers),再依序輸入每一筆數字(key)。
slv_reg0 -> operand1
slv_reg1 -> operand2
slv_reg2 -> operator
slv_reg3 -> inValid
slv_reg4 -> dataResponse
slv_reg5 -> outData
slv_reg6 -> outValid
slv_reg7 -> overflow
state | 說明 |
---|---|
NOP | 閒置狀態,不進行任何操作,並等待inValid訊號。 |
ADD | 進行加法運算,並且在處理完成後拉高calcDone。 |
SUB | 進行減法運算,並且在處理完成後拉高calcDone。 |
MUL | 進行乘法運算,並且在處理完成後拉高calcDone。 |
DONE | 將outValid設為1,並等待PS發回dataResponse訊號 (確認已收到Output data) 後,回到NOP state等待下一次操作。 |
上方程式碼用於確認使用者的input是否在允許範圍內,並且將value寫入對應的AXI slave register存取的位置。
上方程式碼會將Processor hang在while迴圈直到確認Arithmetic module已經做完運算(如果已經完成會發回outValid訊號)。
最後會將從PL得到的Output結果print出來,告知PL已經收到data(將dataResponse對應的slave register拉高),並且將AXI slave register的data進行重置,進行下一次操作。
outData_reg
會在運算的state將已經儲存好的operand進行對應的運算,並且在DONE
時將output值維持住,直到PS回傳dataResponse的訊號後回到NOP
。
outData_reg
因為有預留好多餘的8-bit空間,所以可以透過其在DONE
時的value來判斷是否為overflow。
本問題採用insertion sort的演算法來進行電路撰寫,insertion sort的pseudo code如下所示:
slv_reg0 -> inData
slv_reg1 -> inEN
slv_reg2 -> outData
state | 說明 |
---|---|
INIT | 等待PL端接收到PS傳來的input enable訊號,收到後即跳至LOAD |
LOAD | 將slv_reg0的輸入資料一筆一筆讀進sorting array A中 |
COMPARE | 判斷while_condition,確認 j>=0 and A[j]>key此條件 |
SWAP | 執行上方pseudo code的第6以及第7行 |
LAST | 執行上方pseudo code的第8行 |
上方程式碼的第13行透過for loop將所有輸入的8筆4-bit資料全部存入inData,並將其透過第15行寫入slave_register_0,再透過第16行將input enable的訊號寫入slave_register_1。
第20行則是去讀取PL端輸出的資料,從slave_register_2讀取。
上方圖中輸入8筆資料先後由左到右依序為<3,15,1,4,14,6,0,9>,可以看到input顯示906e41f3,為將8筆資料存入同一個32-bit的u32暫存空間的結果,從LSB至MSB以16進制方式表示與輸入序列相吻合,代表輸入成功寫入slv_reg0。
slv_reg0 -> type
slv_reg1 -> inValid
slv_reg2 -> inData
slv_reg3 -> dataResponse
slv_reg4 -> result
slv_reg5 -> outValid
state | 說明 |
---|---|
NOP | 閒置狀態,不進行任何操作,並等待inValid訊號。 |
HANDLE | 正在處理parity運算,並且在處理完成後拉高calcDone。 |
DONE | 將outValid設為1,並等待PS發回dataResponse訊號 (確認已收到Output data) 後,回到NOP state等待下一次操作。 |
上方程式碼用於確認使用者的input是否在允許範圍內,並且將value寫入對應的AXI slave register存取的位置。
上方程式碼會將Processor hang在while迴圈直到確認ParityGenerator module已經做完運算(如果已經完成會發回outValid訊號)。
最後會將從PL得到的Output結果print出來,告知PL已經收到data(將dataResponse對應的slave register拉高),並且將AXI slave register的data進行重置,進行下一次操作。
counter
和calc_reg
為在HANDLE
時主要作為運算的兩個register:
counter
會在每個cycle遞增直到大於31。calc_reg
在NOP
會重置為0,並且在HANDLE
時和input data對應counter的bit進行XOR運算,最後在DONE
根據不同的parity type將值傳給result_reg
進行output。