姓名 | 學號 |
---|---|
劉永勝 | F94089032 |
蔡宗瑾 | E14083137 |
李宇洋 | E24099025 |
Color code也可稱作hex triplet,而其是由光的三元色RGB(Red, Green, Blue)所組成,每個顏色大小8bit,範圍從0~255,一個顏色有256種組合,透過三元色各個顏色強度的不同可以得到種顏色組合。Color code就是將每個顏色透過對應的三元色強度編碼而成的code,例如紫色其對應的color code是7F1FFF,代表顏色強度(Red, Green, Blue)=(7F,1F,FF)時,人眼可辨識其顏色為紫色。
本設計有兩個RGB燈光需要控制,一個是LED4,其為恆亮某種指定顏色;一個是LED5,其為以呼吸燈的方式亮某種指定顏色。
R_time_in, G_time_in, B_time_in 分別代表RGB的顏色強度,當counter小於個別強度時,RGB都會亮,一旦counter超過其指定強度時,RGB根據其對應強度各自暗掉。
相較於上面直接利用system clk驅動counter_256來顯示顏色,我們呼吸燈採用降頻的方式來呈現,使得人眼可以辨認出呼吸的效果。
透過一個16-bit counter來實現降頻,其範圍是0~0xffff,會根據counter_256每當數到255時才加一,兩種counter如以下:
我們呼吸燈的實現方法是將rgb三個PWM 等比例增加到我們想要的顏色,達到亮度遞增的效果。之後再等比例遞減,達到亮度遞減的效果。
如何遞增、遞減?
本題目要求暗 -> 亮 ->暗
至少要32個phase,則可切成暗->亮
16 phase、亮->暗
16 phase。依照等比例遞增、遞減的方式,將該顏色對應的hex triplet除以16,可得到每個phase需要增加、減少的數值,如下方例子:
紫燈hex triplet對應的rgb PWM分別為7F_1F_FF:
( r ) red PWM = 8'h7F
( g ) green PWM = 8'h1F
( b ) blue PWM = 8'hFF
rgb最大值除以16,分成16個phase:
( r ) 8'h7F / 16 = 8'h7F >> 4 = 4'h7 = R
( g ) 8'h1F / 16 = 8'h1F >> 4 = 4'h1 = G
( b ) 8'hFF / 16 = 8'hFF >> 4 = 4'hF = B
則上方計算出的數值,為每個phase PWM需要增加的量。因此16個phase即可接進數值,因為shift bit的關係,會有餘數問題。
rgb除以16的餘數:
( r ) 8'h7F % 16 = 4'hF = mod R
( g ) 8'h1F % 16 = 4'hF = mod G
( b ) 8'hFF % 16 = 4'hF = mod B
根據上方的計算可得下方式子:
( r ) R * 16 + mod R = 8'h7F
( g ) G * 16 + mod G = 8'h1F
( b ) B * 16 + mod B = 8'hFF
16個phase遞增、遞減,再加一個phase處理餘數。
Dynamic boundary
X_breathing不是像上半部的X_time_in是固定的,它是動態改變的邊界,也就是因為這個動態邊界呈現了呼吸燈的效果,讓原先static lights固定的邊界為hex code,在這裡的呼吸燈成為漸漸遞增又遞減的邊界。
綜觀counter以及breathing的程式碼,可得知X_breathing改變的頻率是,X_breathing會一路從0加到相對應的hex code(最大值),再從最大值遞減回0。
state | 說明 |
---|---|
INCREASING | rgb PWM從0開始逐步遞增 |
ADD_LAST | 加上餘數 |
DECREASING | rgb PWM從最大值逐步遞減 |
SUB_LAST | 減去餘數 |
分割模塊
這個實作分成兩個模塊,分別為PWM_Decoder
和Breath_LED
個別功能如下:
PWM_Decoder
輸入訊號switch,決定輸出顏色的PWM,此PWM輸出訊號會讓Breath_LED接收,為呼吸燈的最大亮度。下表為對應顏色:
switch | color |
---|---|
00 | 7F_1F_FF - Purple Light |
00 | 00_FF_FF - Cyan Light |
00 | FF_FF_00 - Yellow Light |
00 | FF_00_FF - Crimson Light |
Breath_LED
接收PWM_Decoder輸出的顏色PWM最大值,執行上方FSM之功能,達到呼吸燈PWM的遞增遞減
Block Design
Problem 1是手動變換顏色,而Problem 2是自動變換顏色。要實現此功能則模塊PWM_Decoder不能從板子上的switch接收訊號,也就是pynq-z2_v1.0.xdc
不能指名switch腳位。而是要系統自行產生switch訊號切換顏色。
PWM_Decoder
與problem 1功能相同,只是顏色從4個變成6個,則輸入switch
訊號線從2 bit變成3 bit。
Breath_LED
內部狀態機與problem 1相同,但當state從INCREASIN跑到SUB_LAST時,完成一次暗 -> 亮 ->暗
,輸出switch
訊號給PWM_Decoder,則PWM_Decoder根據switch
的數值,給出對應顏色。簡單來說,FSM跑完一圈,則輸出訊號switch
加一,加到5之後歸零。
switch顏色對應如下:
switch | color |
---|---|
0 | FF_00_00 - Red Light |
1 | FF_61_00 - Orange Light |
2 | FF_FF_00 - Yellow Light |
3 | 00_FF_00 - Green Light |
4 | 00_00_FF - Blue Light |
5 | 7F_1F_FF - Purple Light |
default | FF_00_00 - Red Light |