Big5中文字输出

目的 
把想要輸出的字型,寫到一個File裡面,再利用讀檔的方式,透過倚天字碼查表,然後轉換成一連串的101010101,設計成一個testbench使第二組能夠接受
Step1:輸入測資(中文字)
Step2:讀出輸入字的內碼(Big 5)
Step3:以內碼尋找該字在stdfont.15內的位置
Step4:將stdfont.15裡的資料取出成為bitmap 
Step5:將bitmap轉成vwf檔(讓Quartus II能夠讀取)
Step6:寫一個testbench(VHDL)讀取bitmap轉出來的vwf檔 
    以”永”字為例 
先在input檔案內輸入”永”,然後用指令” trans_big5 < test.txt > out.vwf ”讓輸入檔案導入C code執行檔中然後將結果導出至vwf檔
然後下圖為取出之bitmap:

 以下為導出的out.vwf檔


如何找出Big 5 code? 

4種方法:
1.code中使用現成轉Big 5的程式
2.
自己從input的中文字找出該字的Big 5
3.
直接在程式中建立一個Big 5的資料庫
4.
由輸入字的value計算出Big 5(the chosen way)
Code

in = (word[0] << 8) + ( word[1] & 0xFF );

in = in & 0xFFFF;          //word = 輸入(中文字)in = Big 5

 

Make Bitmap
stdfont.15中存有大部分Big 5碼中文字的bitmap
Step1:以Big 5碼找出中文字的序列碼
    HI = in/256; // HI = 高位碼
    LO = in%256; // LO = 低位碼
    if(LO >= 161)
        SerCode = (HI - 161) * 157 + (LO - 161) + 1 + 63
    else
        SerCode = (HI - 161) * 157 + (LO - 64) + 1
Step2:以序列碼找出該字在stdfont.15中的檔案位置位移量(Offset)
Step3:該字的bitmap即存在stdfont.15中的第Offset個byte開始的30 bites。
    Code:
    if(Ser >= 472 && Ser <= 5872)
            Offset = (Ser-472)*30; //常用字
    else if(Ser >= 6281 && Ser <= 13973)
            Offset = (Ser-6281)*30+162030; //非常用字
    else
            Offset=-1000000; //該字的bitmap沒有出現在stdfont.15中

以”一”為例:
“一”的Big 5碼為0xA440
HI = 0xA4 = 164, LO = 0x40 = 64
LO < 161
SerCode = (HI - 161) * 157 + (LO - 64) + 1 = 472
SerCode >= 472 && SerCode <= 5872
OffSet = (SerCode - 472) * 30 = 0
“一”的bitmap就存在stdfount.15的第0 ~ 29byte中

Transfor Bitmap
將取出來的bitmap改成以1 bit為單位的儲存格式(否則Quartus II無法讀取)
Code:
for(i = 0;i<15;++i){
        for(j = 0;j<2;++j){                

                Wait_to_trans[i][(8*j)+0] = ( bmap[i][j] >> 7 ) & 1 ;        

                Wait_to_trans[i][(8*j)+1] = ( bmap[i][j] >> 6 ) & 1 ;                     

                Wait_to_trans[i][(8*j)+2] = ( bmap[i][j] >> 5 ) & 1 ;        

                Wait_to_trans[i][(8*j)+3] = ( bmap[i][j] >> 4 ) & 1 ;                        

                Wait_to_trans[i][(8*j)+4] = ( bmap[i][j] >> 3 ) & 1 ;        

                Wait_to_trans[i][(8*j)+5] = ( bmap[i][j] >> 2 ) & 1 ;                         

                Wait_to_trans[i][(8*j)+6] = ( bmap[i][j] >> 1 ) & 1 ;        

                Wait_to_trans[i][(8*j)+7] = bmap[i][j] & 1 ;
        }
}    // bmap = 原來的bitmap  Wait_to_trans = 轉換後的bitmap

Make Testbench
有兩種方法:
1.用VHDL讀出前面轉出來的bitmap
2.使用C code印出VHDL的testbench(the chosen way)
    Code:
    printf(“……………”);
    while((c = fgetc(fptr)) != EOF){
         if(c == '0'){
            printf("        LEVEL 0 FOR 4000000.0;\n");
            i=i+4 ;
            k++ ;
         }
         else if(c == '1'){
            printf("        LEVEL 1 FOR 4000000.0;\n");
            i=i+4 ;
            k++ ;
         }
      }
    printf(“……………”);

輸入/輸出格式: 
input           :       in              std_logic ;
inclk           :       in              std_logic ;
inset           :       in              std_logic ;
output          :       out             std_logic_vector( 0 to 14 ) ;
clk_48MHz      :       in              std_logic );

輸入資料格式: 
每筆輸入的資料包含:速度(2 bits)、反白(1 bit)、閃爍(1 bit)與8個15*16 dots的陣列,合計1924 bits。
        速度的表示方式為:
00最快(1秒跳2次) 
01中快(1秒1次)
10中慢(1.5秒1次)
11最慢(2秒1次)
反白bit設成0代表不反白正常, 設成1代表全部反白。
閃爍bit設成0代表不閃爍, 設成1時移動字的時候會有閃爍特效。

啟動/資料輸入方式: 
        Inset在資料輸入的過程中設定為1,輸入完成後設定為0,並開始平移字幕。
        Input即為輸入的資料,每當inclk跳成1的時候接收1個bit的資料。

輸出方式與頻率: 
        每次送出15個bits(即為一直行的dots)。頻率為每秒送出8個字,即為每秒共送出 16 * 8 * 30 = 3840次資料,每次15 bits。

Difficulty: 
為了能夠調整速度就需要設定一個shiftclk。但是若input也設定一個clock,就需要有兩個clocks,則buffer會有multiple drive的問題。

Solution:
讓buffer只聽一個clock的指令,不過這個clock在inset = 0和1時分別為的shiftclk 與inclk訊號:
process ( inset , mixclk , inclk , shiftclk )
begin
        if ( inset = '1' ) then
                mixclk <= inclk;
        else
                mixclk <= shiftclk;
        end if;
end process;
如此一來buffer只要mixclk的訊號即可。

Difficulty:閃爍 
要達成閃爍的效果,必須要將顯示的文字與位置記錄下來,並且和空白畫面交互顯示。因此,必須每次更動顯示的文字,在執行上有相當程度的困難。

Solution: 
        另設一twinkleclk_count,配合shiftclk來控制twinkleclk:
        process
        begin
        wait until ( shiftclk'event and shiftclk = '1' );
                if ( twinkleclk_count < "01" ) then
                        twinkleclk_count <= twinkleclk_count + 1;
                else
                        twinkleclk_count <= "00";
                        twinkleclk <= not twinkleclk;
                end if;
        end process;
        並將allzero和outputbuffer交互顯示:
        -- empty
        if ( twinkleclk = '0' ) then
                output <= allzero;
        -- show
        else
                output <= outputbuffer;
        end if;



http://www.solutioninside.com/~jackiekan/2007/Project/LED_Board/Home.html

 

posted @ 2011-09-01 09:27  stdtrekman  阅读(3347)  评论(0编辑  收藏  举报