모종의 음모/HDLC2022. 8. 29. 14:42

 

Flag field가 아닌 Data에 0x7E가 있는지 확인

0x7E -< 0x7D, 0x5E를 삽입

[링크 : https://blog.daum.net/trts1004/12109121]

 

232와 같은 비동기 전송일 경우 bit stuff를 적용하지 않는다고..?

Synchronous framing
Because a flag sequence consists of six consecutive 1-bits, other data is coded to ensure that it never contains more than five 1-bits in a row. This is done by bit stuffing: any time that five consecutive 1-bits appear in the transmitted data, the data is paused and a 0-bit is transmitted.


Asynchronous framing
When using asynchronous serial communication such as standard RS-232 serial ports, synchronous-style bit stuffing is inappropriate for several reasons:

Bit stuffing is not needed to ensure an adequate number of transitions, as start and stop bits provide that,
Because the data is NRZ encoded for transmission, rather than NRZI encoded, the encoded waveform is different,
RS-232 sends bits in groups of 8, making adding single bits very awkward, and
For the same reason, it is only necessary to specially code flag bytes; it is not necessary to worry about the bit pattern straddling multiple bytes.
Instead asynchronous framing uses "control-octet transparency", also called "byte stuffing" or "octet stuffing". The frame boundary octet is 01111110, (0x7E in hexadecimal notation). A "control escape octet", has the value 0x7D (bit sequence '10111110', as RS-232 transmits least-significant bit first). If either of these two octets appears in the transmitted data, an escape octet is sent, followed by the original data octet with bit 5 inverted. For example, the byte 0x7E would be transmitted as 0x7D 0x5E ("10111110 01111010"). Other reserved octet values (such as XON or XOFF) can be escaped in the same way if necessary.

The "abort sequence" 0x7D 0x7E ends a packet with an incomplete byte-stuff sequence, forcing the receiver to detect an error. This can be used to abort packet transmission with no chance the partial packet will be interpreted as valid by the receiver.

[링크 : https://en.wikipedia.org/wiki/High-Level_Data_Link_Control]

Posted by 구차니
모종의 음모/HDLC2022. 8. 29. 14:28

잘 작동하는지 모름, 걍 밑바닥에서 부터 작성함

 

$ cat hdlc_nrzi_enc.c
#include <stdio.h>

void main()
{
        unsigned char data[10] =                {0x7E, 0x11, 0x22, 0x33, 0x1E, 0x0A, 0x7E, 0x00, 0x00, 0x00};
        unsigned char lsbmsb[10] =              {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        unsigned char bitstuff[10] =    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        unsigned char nrzi[10] =                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

        int i = 0;
        int b = 0;

        // msb to lsb, data order change
        printf("bitwise LSB convert ----------------------------------------\n");
        for(i = 0; i < 10; i++)
        {
                unsigned char tempval = 0;
                unsigned char orival = 0;
                orival = data[i];
                for(b = 0; b < 8; b++)
                {
                        tempval |= ((orival & 0x01) << (7 - b));
                        orival = orival >> 1;
                }
                lsbmsb[i] = tempval;
                printf("%02X -> %02X\n",data[i],lsbmsb[i]);
        }

        // zrzi
        printf("NRZ-I ----------------------------------------\n");
        unsigned char last = 0;
        unsigned char out = 0;
        for(i = 0; i < 80; i++)
        {
                last = (lsbmsb[i / 8] >> (7 - (i % 8))) & 0x01;
//              printf("i:%d l:%d ", i, last);
                if(last == 0)
                        out=(out==0?1:0);
//              printf("o:%d\n", out);
                nrzi[i / 8] |= out << (7 - (i % 8));

                if(i % 8 == 7)
                        printf("%02X -> %02X\n", lsbmsb[i/8],nrzi[i/8]);
        }
}
$ ./enc
bitwise LSB convert ----------------------------------------
7E -> 7E
11 -> 88
22 -> 44
33 -> CC
1E -> 78
0A -> 50
7E -> 7E
00 -> 00
00 -> 00
00 -> 00
NRZ-I ----------------------------------------
7E -> FE
88 -> 5A
44 -> D2
CC -> 22
78 -> FA
50 -> CA
7E -> FE
00 -> AA
00 -> AA
00 -> AA

 

 

$ cat hdlc_nrzi_dec.c
#include <stdio.h>

void main()
{
        unsigned char data[10] =                {0xFE, 0x5A, 0xD2, 0x22, 0xFA, 0xCA, 0xFE, 0x00, 0x00, 0x00};
        unsigned char lsbmsb[10] =              {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        unsigned char bitstuff[10] =    {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
        unsigned char nrzi[10] =                {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};

        int i = 0;
        int b = 0;

        // zrzi
        printf("NRZ-I ----------------------------------------\n");
        unsigned char last = 0;
        unsigned char curr = 0;
        unsigned char out = 0;
        for(i = 0; i < 80; i++)
        {
                curr = (data[i / 8] >> (7 - (i % 8))) & 0x01;
//              printf("i:%d l:%d c:%d ", i, last, curr);
                if(last != curr)
                        out = 0;
                else out = 1 ;
                last = curr;
//              printf("o:%d\n", out);
                nrzi[i / 8] |= out << (7 - (i % 8));

                if(i % 8 == 7)
                        printf("%02X -> %02X\n", data[i/8],nrzi[i/8]);
        }

        // msb to lsb, data order change
        printf("bitwise LSB convert ----------------------------------------\n");
        for(i = 0; i < 10; i++)
        {
                unsigned char tempval = 0;
                unsigned char orival = 0;
                orival = nrzi[i];
                for(b = 0; b < 8; b++)
                {
                        tempval |= ((orival & 0x01) << (7 - b));
                        orival = orival >> 1;
                }
                lsbmsb[i] = tempval;
                printf("%02X -> %02X\n",nrzi[i],lsbmsb[i]);
        }

}
$ ./dec
NRZ-I ----------------------------------------
FE -> 7E
5A -> 88
D2 -> 44
22 -> CC
FA -> 78
CA -> 50
FE -> 7E
00 -> FF
00 -> FF
00 -> FF
bitwise LSB convert ----------------------------------------
7E -> 7E
88 -> 11
44 -> 22
CC -> 33
78 -> 1E
50 -> 0A
7E -> 7E
FF -> FF
FF -> FF
FF -> FF

'모종의 음모 > HDLC' 카테고리의 다른 글

HDLC bit stuff  (0) 2022.08.29
hdlc 프로토콜 - bit stuffing, endian?  (0) 2022.08.26
HDLC FCS ccitt-1 16bit crc  (0) 2021.12.06
HDLC 프로토콜(High level Data Link Control)  (0) 2021.07.27
Posted by 구차니
모종의 음모/HDLC2022. 8. 26. 15:47

아.. 이런 변수가 하나 더 있었던 건가..

111111 가 전송되려면 1111101 이런식으로 전송되어야 한다.

(그런데.. 진짜 데이터가 111110 이면 어떡해야 하지? 어짜피 5개가 되었으니 1111100이 되는건가?)

Because a flag sequence consists of six consecutive 1-bits, other data is coded to ensure that it never contains more than five 1-bits in a row. This is done by bit stuffing: any time that five consecutive 1-bits appear in the transmitted data, the data is paused and a 0-bit is transmitted.

HDLC transmits bytes of data with the least significant bit first (not to be confused with little-endian order, which refers to byte ordering within a multi-byte field).

[링크 : https://en.wikipedia.org/wiki/High-Level_Data_Link_Control]

 

The NRZI coding scheme transmits a 0 bit as a signal transition, and a 1 bit as no change. In this case, bit stuffing is most easily described as the insertion of a 0 bit after a long run of 1 bits.

[링크 : https://en.wikipedia.org/wiki/Bit_stuffing]

 

[링크 : https://copycode.tistory.com/79]

[링크 : https://itwiki.kr/w/HDLC]

[링크 : https://goodgid.github.io/What-is-HDLC/]

 

+

 

 

0,1 눈대중으로 변환해서 연속된 0이나 1에 대한 오류가 존재하지만

전반적으로 비트가 뒤집힌 형태로 전송됨을 확인함. (바이트 내에서 LSB가 MSB에 존재함)

7E 11 22 33 1E 0A 7F
01111110 00010001 00100010 00110011 00011110 00001010 01111111 (raw)
01111110 10110100 10010110 10001000 10111110 10100110 01111111 (nrzi)

11111110 01011010 11010010 00100010 11111010 11001010 11111110 (수신데이터)
01111111 01011010 01001011 01000100 01011111 01010011 01111111 (수신데이터 바이트 단위 순서 변경)

 

'모종의 음모 > HDLC' 카테고리의 다른 글

HDLC bit stuff  (0) 2022.08.29
hdlc nrzi encoder / decoder (bit stuff 제외)  (0) 2022.08.29
HDLC FCS ccitt-1 16bit crc  (0) 2021.12.06
HDLC 프로토콜(High level Data Link Control)  (0) 2021.07.27
Posted by 구차니
모종의 음모/HDLC2021. 12. 6. 18:22
Posted by 구차니
모종의 음모/HDLC2021. 7. 27. 16:57

'모종의 음모 > HDLC' 카테고리의 다른 글

HDLC bit stuff  (0) 2022.08.29
hdlc nrzi encoder / decoder (bit stuff 제외)  (0) 2022.08.29
hdlc 프로토콜 - bit stuffing, endian?  (0) 2022.08.26
HDLC FCS ccitt-1 16bit crc  (0) 2021.12.06
Posted by 구차니

여전히 화면은 안나오지만 일단 modelsim에서 패턴은 대충 확인했으니

이제 맞춰나가면 될 듯..

module vga640x480(

input clk,

input rst,

output [7:0] LED,

output hsync,

output vsync,

output [3:0] r,

output [3:0] g,

output [3:0] b

);


parameter HSYNC = 190;

parameter HBP = (190 + 96);

parameter HVID = (190 + 96 + 1271);

parameter HFP = (190 + 96 + 1271 + 32);

parameter HTOTAL = 1589;


parameter VSYNC = 3200;

parameter VBP = (3200 + 52400);

parameter VVID = (3200 + 52400 + 762650);

parameter VFP = (3200 + 52400 + 762650 + 15900);

parameter VTOTAL = 834150;


reg [19:0] cnt;


always @ (posedge clk or negedge rst)

begin

if (~rst)

cnt <= 0;

else

begin

if(cnt < VTOTAL) cnt <= cnt + 1;

else cnt <= 0;

end

end


assign LED[0] = ~vsync;

assign LED[1] = ~hsync;

assign r[3:0] = (((VBP < cnt) && (cnt < VVID)) && ((HBP < (cnt % HTOTAL)) && ((cnt % HTOTAL) < HVID))) ? 4'b1111 : 4'b0000;

assign g[3:0] = (((VBP < cnt) && (cnt < VVID)) && ((HBP < (cnt % HTOTAL)) && ((cnt % HTOTAL) < HVID))) ? 4'b1111 : 4'b0000;

assign b[3:0] = (((VBP < cnt) && (cnt < VVID)) && ((HBP < (cnt % HTOTAL)) && ((cnt % HTOTAL) < HVID))) ? 4'b1111 : 4'b0000;

assign hsync = ((cnt % HTOTAL) < HSYNC)? 0 : 1;

assign vsync = ((cnt         ) < VSYNC)? 0 : 1;


endmodule 


다시 보니.. 비디오 출력 하는 부분에서 &&대신 & 쓰지 않나

조건식 비교 범위를 반대로 하지 않나(그러니 계속 0이지) 완전 난리 부르스. ㄷㄷ


타이밍이 잘못되었나.. 왜 안나올까...


Posted by 구차니

usec 단위로 했었는데.. Hysnc의 길이가 왜.. 3.77usec?

아무튼.. 다시 아래 문서대로 계산을 해보니 값이 좀 많이 다르게 나온다.

vga_640x480.xlsx

2018/06/05 - [모종의 음모/DE0-Nano VGA] - vga 640x480 실패중 그리고 800x600x60


---

VESA DMT 문서에 의하면(공식인지 모르겠지만)



흐음.. 여전히 안되네...

module vga640x480(

input clk,

input rst,

output [7:0] LED,

output hsync,

output vsync,

output [3:0] r,

output [3:0] g,

output [3:0] b

);


parameter HSYNC = 190;

parameter HBP = (190 + 96);

parameter HVID = (190 + 96 + 1271);

parameter HFP = (190 + 96 + 1271 + 32);

parameter HTOTAL = 1589;


parameter VSYNC = 3200;

parameter VBP = (3200 + 52400);

parameter VVID = (3200 + 52400 + 762650);

parameter VFP = (3200 + 52400 + 762650 + 15900);

parameter VTOTAL = 834150;


reg [19:0] cnt;


always @ (posedge clk or negedge rst)

begin

if (~rst)

begin

cnt <= 0;

end

else

begin

if(cnt < VTOTAL)

begin

cnt <= cnt + 1;

/*

if((cnt % HTOTAL) < HSYNC)

hsync <= 0;

else hsync <= 1;

if(cnt < VSYNC)

vsync <= 0;

else vsync <= 1;


if(vsync & hsync)

begin

r <= 4'b1111;

g <= 4'b1111;

b <= 4'b1111;

end

else

begin

r <= 4'b0000;

g <= 4'b0000;

b <= 4'b0000;

end

*/

end

else

cnt <= 0;

end

end


assign LED[0] = ~vsync;

assign LED[1] = ~hsync;

assign r[3:0] = ((VVID < cnt & VFP < cnt) & (HVID < (cnt % HTOTAL) && (cnt % HTOTAL) < HFP)) ? 4'b1111 : 4'b0000;

assign g[3:0] = ((VVID < cnt & VFP < cnt) & (HVID < (cnt % HTOTAL) && (cnt % HTOTAL) < HFP)) ? 4'b1111 : 4'b0000;

assign b[3:0] = ((VVID < cnt & VFP < cnt) & (HVID < (cnt % HTOTAL) && (cnt % HTOTAL) < HFP)) ? 4'b1111 : 4'b0000;

assign hsync = ((cnt % HTOTAL) < HSYNC)? 0 : 1;

assign vsync = ((cnt         ) < VSYNC)? 0 : 1;


endmodule 




Posted by 구차니

DE0-nano에 LemonLite RGB 보드 사용

모니터 마다 해상도 출력이 좀 다른데 머가 문제일까..

일단 눈을 띄우는데는 성공했으니 뭐가 문제인지는 좀 찾아 봐야 할 듯..



vga640x480 vga(

CLOCK_50,

KEY[0],

LED,

GP0[6],

GP0[5],

{GP0[16],GP0[19],GP0[18],GP0[21]},

{GP0[12],GP0[15],GP0[14],GP0[17]},

{GP0[8],GP0[9],GP0[10],GP0[13]}

); 


module vga640x480(

input clk,

input rst,

output [7:0] LED,

output reg hsync,

output reg vsync,

output [3:0] r,

output [3:0] g,

output [3:0] b

);


reg clk25;

reg [9:0] horizontal_counter;

reg [9:0] vertical_counter;


reg [9:0] X;

reg [9:0] Y;


wire [7:0] red;

wire [7:0] green;

wire [7:0] blue;


assign r[3:0] = ((horizontal_counter >= 144) 

&& (horizontal_counter < 784) 

&& (vertical_counter >=39)

&& (vertical_counter < 519)) ? red : 4'b000; 

assign g[3:0] = ((horizontal_counter >= 144) 

&& (horizontal_counter < 784) 

&& (vertical_counter >=39)

&& (vertical_counter < 519)) ? green : 4'b000; 

assign b[3:0] = ((horizontal_counter >= 144) 

&& (horizontal_counter < 784) 

&& (vertical_counter >=39)

&& (vertical_counter < 519)) ? blue : 4'b000; 

assign red =   ((horizontal_counter >= 144)&&(horizontal_counter < 344) ) ? 4'b1111 : 4'b0000;

assign green = ((horizontal_counter >= 344)&&(horizontal_counter < 544) ) ? 4'b1111 : 4'b0000;

assign blue =  ((horizontal_counter >= 544)&&(horizontal_counter < 784) ) ? 4'b1111 : 4'b0000;


always @(posedge clk)

begin


if (clk25 == 0)

begin

   clk25 <= 1;

end   

else

begin

clk25 <= 0;

   end

end



always @(posedge clk25)

begin

if ((horizontal_counter > 0) && (horizontal_counter < 97))// -- 96+1

begin

hsync <= 0;

end

else

begin

hsync <= 1;

end 

if ((vertical_counter > 0 ) && (vertical_counter < 3 )) //-- 2+1

begin

vsync <= 0;

end

else

begin

vsync <= 1;

end

horizontal_counter <= horizontal_counter+1;

    

if (horizontal_counter == 800) 

begin

vertical_counter <= vertical_counter+1;

horizontal_counter <= 0;

end

    

if (vertical_counter == 521)

begin

vertical_counter <= 0;

end

end



endmodule  

[링크 : https://github.com/pmezydlo/DE0-Nano-SOC-VGA/blob/master/vgaram.v]

Posted by 구차니

소스 코드 수정중인데 안나오네

vga640x480 vga(

CLOCK_50,

KEY[0],

LED,

GP0[6],

GP0[5],

{GP0[16],GP0[19],GP0[18],GP0[21]},

{GP0[12],GP0[15],GP0[14],GP0[17]},

{GP0[8],GP0[9],GP0[10],GP0[13]}

); 


module vga640x480(

input clk,

input rst,

output [7:0] LED,

output hsync,

output vsync,

output [3:0] r,

output [3:0] g,

output [3:0] b

);


parameter HSYNC = 189;

parameter HBP = (HSYNC + 95);

parameter HVID = (HBP + 1260);

parameter HFP = (HVID + 47);


parameter VSYNC = 3000;

parameter VBP = (VSYNC + 51000);

parameter VVID = (VBP + 762500);

parameter VFP = (VVID + 17500);


reg [19:0] cnt;


always @ (posedge clk or negedge rst)

begin

if (!rst)

begin

cnt <= 0;

end

else

begin

cnt <= cnt + 1;

if(cnt > 834000)

cnt <= 0;

end

end


assign hsync = ((cnt % 1590) < 189) ? 0 : 1;

assign vsync = (cnt < 3000) ? 0 : 1;

assign r = ((hsync & vsync) == 1 ? 4'b1111 : 4'b0000);

assign g = ((hsync & vsync) == 1 ? 4'b1111 : 4'b0000);

assign b = ((hsync & vsync) == 1 ? 4'b1111 : 4'b0000);

assign LED[0] = ~vsync;

assign LED[1] = ~hsync;


endmodule 


V sync는 59.95

H sync는 31.31kHz 이고


sync 길이도 파형도 맞는거 같은데..

Vsync 60us 근처

Hsync 4us 근처


왜 안될까...



+

module vga800x600x60(

input clk,

input rst,

output [7:0] LED,

output hsync,

output vsync,

output [3:0] r,

output [3:0] g,

output [3:0] b

);


parameter HSYNC = 160;

parameter HBP = (HSYNC + 95);

parameter HVID = (HBP + 1260);

parameter HFP = (HVID + 47);


parameter VSYNC = 5300;

parameter VBP = (VSYNC + 51000);

parameter VVID = (VBP + 762500);

parameter VFP = (VVID + 17500);


reg [19:0] cnt;


always @ (posedge clk or negedge rst)

begin

if (!rst)

begin

cnt <= 0;

end

else

begin

cnt <= cnt + 1;

if(cnt > 828950)

cnt <= 0;

end

end


assign hsync = ((cnt % 1320) < 160) ? 0 : 1;

assign vsync = (cnt < 5300) ? 0 : 1;

assign r = ((hsync & vsync) == 1 ? 4'b1111 : 4'b0000);

assign g = ((hsync & vsync) == 1 ? 4'b1111 : 4'b0000);

assign b = ((hsync & vsync) == 1 ? 4'b1111 : 4'b0000);

assign LED[0] = ~vsync;

assign LED[1] = ~hsync;


endmodule  



For VESA 800*600 @ 60Hz: 

Fh (kHz) :37.88 

A (us) :26.4 

B (us) :3.2 

C (us) :2.2 

D (us) :20.0 

E (us) :1.0 


Fv (Hz) :60.32 

O (ms) :16.579 

P (ms) :0.106 

Q (ms) :0.607 

R (ms) :15.84 

S (ms) :0.026 

[링크 : http://www.epanorama.net/documents/pc/vga_timing.html]


+

640x480x60 에 빨간화면 확인

vga640x480 vga(

CLOCK_50,

KEY[0],

LED,

GP0[6],

GP0[5],

{GP0[16],GP0[19],GP0[18],GP0[21]},

{GP0[12],GP0[15],GP0[14],GP0[17]},

{GP0[8],GP0[9],GP0[10],GP0[13]}

); 


모니터에 따라 인식이 느리거나 안되기도 하네..

848x640x60 으로 인식... 머야(요즘 24인치 FHD LCD 모니터)

module vga640x480(

input clk,

input rst,

output [7:0] LED,

output reg hsync,

output reg vsync,

output [3:0] r,

output [3:0] g,

output [3:0] b

);


reg clk25;

reg [9:0] horizontal_counter;

reg [9:0] vertical_counter;


reg [9:0] X;

reg [9:0] Y;


wire [7:0] red;

wire [7:0] green;

wire [7:0] blue;


assign r[3:0] = ((horizontal_counter >= 144) 

&& (horizontal_counter < 784) 

&& (vertical_counter >=39)

&& (vertical_counter < 519)) ? 4'b1111 : 4'b000; 

assign g[1:0] = ((horizontal_counter >= 144) 

&& (horizontal_counter < 784) 

&& (vertical_counter >=39)

&& (vertical_counter < 519)) ? 4'b1111 : 4'b000; 

assign b[2:0] = ((horizontal_counter >= 144) 

&& (horizontal_counter < 784) 

&& (vertical_counter >=39)

&& (vertical_counter < 519)) ? 4'b1111 : 4'b000; 

assign red =   ((horizontal_counter >= 144)&&(horizontal_counter < 344) ) ? 4'b1111 : 4'b0000;

assign green = ((horizontal_counter >= 344)&&(horizontal_counter < 544) ) ? 4'b1111 : 4'b0000;

assign blue =  ((horizontal_counter >= 544)&&(horizontal_counter < 784) ) ? 4'b1111 : 4'b0000;


always @(posedge clk)

begin


if (clk25 == 0)

begin

   clk25 <= 1;

end   

else

begin

clk25 <= 0;

   end

end



always @(posedge clk25)

begin

if ((horizontal_counter > 0) && (horizontal_counter < 97))// -- 96+1

begin

hsync <= 0;

end

else

begin

hsync <= 1;

end 

if ((vertical_counter > 0 ) && (vertical_counter < 3 )) //-- 2+1

begin

vsync <= 0;

end

else

begin

vsync <= 1;

end

horizontal_counter <= horizontal_counter+1;

    

if (horizontal_counter == 800) 

begin

vertical_counter <= vertical_counter+1;

horizontal_counter <= 0;

end

    

if (vertical_counter == 521)

begin

vertical_counter <= 0;

end

end

endmodule  


[링크 : https://github.com/pmezydlo/DE0-Nano-SOC-VGA/blob/master/vgaram.v]

Posted by 구차니

reset키(key[0])를 누르고있는 동안에는 영상이 나온다.

단순하게 posedge를 negedge로 바꾸려고 하는데 에러나네.. ㅠㅠ


빨강이 옆에 번지는건 왜일까..


800x600 72Hz 라고 출력된다.



vga_demo vga(

CLOCK_50,

KEY[0],

GP0[16],

GP0[12],

GP0[8],

GP0[6],

GP0[5],

); 


/*

VGA Demo 800x600 at 72Hz

http://www-mtl.mit.edu/Courses/6.111/labkit/vga.shtml

800x600, 72Hz 50.000 800 56 120 64 600 37 6 23

Pixel Clock (MHz): 50.000 

Horizontal (in Pixels)

    Active Video: 800 (16us)

    Front Porch:   56 (1.12us)

    Sync Pulse:   120 (2.4us)

    Back Porch:    64 (1.28us)

        Total pixel clock ticks: 1040 (20.8us)

Vertical (in Lines, so x20.8us)

    Active Video: 600 (12480us)

    Front Porch:   37 (769.6us)

    Sync Pulse:     6 (124.8us)

    Back Porch:    23 (478.4us)

        Total pixel clock ticks: 666 (13.32us)

Total pixel clock ticks: 692,640

50,000,000 / 692,640 = 72.187572188 = 72Hz

1 pixel clock = 1/50Mhz = 20ns = 0.02us

*/


module vga_demo

    (

        CLOCK_50,

        RESET,

        VGA_RED,

        VGA_GREEN,

        VGA_BLUE,

        VGA_HS,

        VGA_VS

    );

    input CLOCK_50;

    input RESET;

    output VGA_RED;

    output VGA_GREEN;

    output VGA_BLUE;

    output VGA_HS;

    output VGA_VS;


    /* Internal registers for horizontal signal timing */

    reg [10:0] hor_reg; // to count 1040 different values up to 1039

    reg hor_sync;

    wire hor_max = (hor_reg == 1039); // to tell when a line is full


    /* Internal registers for vertical signal timing */

    reg [9:0] ver_reg; // to count 666 different values up to 665

    reg ver_sync;

    reg red, green, blue;

    wire ver_max = (ver_reg == 665); // to tell when a line is full


    // Code


    

    /* Running through line */

    always @ (posedge CLOCK_50 or posedge RESET) begin


        if (RESET) begin 

            hor_reg <= 0;

            ver_reg <= 0;

        end

        else if (hor_max) begin

            hor_reg <= 0;


            /* Running through frame */

            if (ver_max)

                ver_reg <= 0;

            else

            ver_reg <= ver_reg + 1;


        end else

            hor_reg <= hor_reg + 1;


    end

    

    always @ (posedge CLOCK_50 or posedge RESET) begin

    

        if (RESET) begin 

            hor_sync <= 0;

            ver_sync <= 0;

        end

        else begin


            /* Generating the horizontal sync signal */

            if (hor_reg == 856)      // video (800) + front porch (56)

                hor_sync <= 1;       // turn on horizontal sync pulse

            else if (hor_reg == 976) // video (800) + front porch (56) + Sync Pulse (120)

                hor_sync <= 0;       // turn off horizontal sync pulse


            /* Generating the vertical sync signal */

            if (ver_reg == 637)      // LINES: video (600) +  front porch (37)

                ver_sync <= 1;       // turn on vertical sync pulse

            else if (ver_reg == 643) // LINES: video (600) + front porch (37) + Sync Pulse (6)

                ver_sync <= 0;       // turn off vertical sync pulse


                

            // Draw a single square.

            if (hor_reg >= 100 && hor_reg <= 200 && ver_reg >= 100 && ver_reg <= 200) begin

                red <= 1;

                green <= 0;

                blue <= 0;

            end 

            else begin

                red <= 1;

                green <= 1;

                blue <= 1;

            end

                

        end

    end


    // Send the sync signals to the output, inverted as the sync pulse is low.

    // Maybe wrong as this doc says pulse id positive http://tinyvga.com/vga-timing/800x600@72Hz

    assign VGA_HS = ~hor_sync;

    assign VGA_VS = ~ver_sync;

    

    // Send a pattern of colours (based on the registry bits) but do not output anything during the synchronization periods

    //assign VGA_RED = (!hor_reg[0] && !ver_reg[0] && ver_reg < 600 && hor_reg < 800);

    //assign VGA_GREEN = (!hor_reg[1] && !ver_reg[1] && ver_reg < 600 && hor_reg < 800);

    //assign VGA_BLUE = (!hor_reg[2] && !ver_reg[2] && ver_reg < 600 && hor_reg < 800);

    

    assign VGA_RED =  red && ver_reg < 600 && hor_reg < 800;

    assign VGA_GREEN = green && ver_reg < 600 && hor_reg < 800;

    assign VGA_BLUE = blue && ver_reg < 600 && hor_reg < 800;    

    

    // http://gerfficient.com/2013/02/11/fpga-to-vga-using-de0-nano/

    

endmodule 

[링크 : https://github.com/theapi/de0-nano/blob/master/vga/experiment/vga_demo.v]

Posted by 구차니