Baud generator
시리얼링크의 최고 속도는 115200 baud 라고 이전 포스트에서 말을 했었다. 다른 속도도 손쉽게 만들어 낼수 있다.
요즘 FPGA는 일반적으로 115200Hz보다 더 빠른 속도로 동작을 한다.(RS-232는 현재 오래된,느린 표준일뿐이다.) 즉, 이말은 고속의 클럭을 해당 속도(여기선 115200으로)로 나누어야 한다는 것을 의미한다.
Synchronous tick from a 1.8432Mhz clock
전통적으로 RS-232칩은 1.8432Mhz 클럭을 사용해왔다. 이는 표준속도주파스를 만들기 쉽기때문이다. 그래서 여기선 1.8432Mhz클럭을 사용한다고 가정한다.
1.8432Mhz 를 16으로 나누면, 1152000Hz가 나온다. ^^
fpga4fun.com 의 FPGA interface projects 섹션에 serial interface 부분이 있다. 그 RS-232 부분의 번역본이다.
이문서의 원본은 http://www.fpga4fun.com/SerialInterface2.html 에서 찾을수 있다. from 후니유.
공부를 위한 목적으로 번역을 하였기때문에 오역,맘대로의역이 있어도 내맘이다 ㅋㅋ
reg[3:0] BaudDivCnt;
always @(posedge clk) BaudDivCnt <= BaudDivCnt +1;
wire BaudTick = (BaudDivCnt==15);
BaudTick 은 16번에 한번씩 클러킹되니, 115200이 나오게 된다.
혹시 프로그래밍을 모른다면, 한번 알아보기를 바란다. 그리 어려운(?)건 없다.
Free버전이 많이 나와있다. FPGA벤더들이 제공하는 것들이 많으니(당연히 약간의 제한이 있다.) Xilinx 의 ISE WebPack도 있으며, Altera의 Quartus II Web Edition 도 있다.
기본적인 VHDL 문법을 알면 해결될 문제이다.
Xilinx의 ISE WebPack 9.2i(윈도우32bit) 는 여기(웹인스톨 버전이다. 16MB)
single file버전은 여기(1.7G의 용량이다. DVD를 준비하라)
Lab install버전은 여기(741MB)
Altera의 Quartus web edition 버전은 여기서 받을 수 있다. 등록을 해야하니
찾아가 보자.
Xilnx든 Altera든 툴들을 web용(혹은 student용)이라는 명목으로 free버전이 존재한다. 다운받을때 몇가지의 등록들이 필요로한다.(이름이며, 직책등의)
간단한 등록을 하고, 다운을 받아 설치하면, 잘동작을 하니, 인내심을 가지고 등록을 하자
(약간 느린게 짜증 지대루다...)
설치및 간단한 사용방법등은 후에 포스팅을 할 예정이므로 참고만 하자.
Synchronous tick from any frequency
예전의 제너레이터는 1.8432Mhz 클럭을 가졌었다. 그런데 당신이 2Mhz를 가졌다면?
2Mhz 클럭에서 115200hz르 만들어 내려면 17.1111... 로 나누어야 하지만, 불가능하다.
결국 방법은 17과 18을 일정 비율로 나누는 방법을 이용하는 것이다.
간단한 C 코드다.
while(1)
{
acc += 115200;
if(acc >= 2000000) printf("*"); else printf(" ");
acc %= 2000000;
}
여기서 * 는 정확한 비율로 나오게 된다. 17.36111 마다.
FPGA에서 같은 효과를 보여주기 위해서 시리얼 인터페이스가 Baud frequency generator에서 어느정도의 에러가 난다는것을 알아야 한다.
FPGA baud generator
이상적인 ratio 를 위해서, 17.356을 사용한다.
// ACC는 10비트. 캐리아웃을 위해서 1비트를 사용한다.[10]
reg[10:0] acc; // 전부 11비트가 된다.
always @(posedge clk)
acc <= acc[9:0] + 59; // 10비트만 사용.
wire BaudTick = acc[10]; // 11번째 비트는 캐리아웃.
2Mhz 를 사용할 경우 BaudTick은 115234 가 나온다.(0.03%의 에러발생)
Parameterized FPGA baud generator
이전 디자인에서 10비트 Acc를 사용했다. 그러나 클럭 주파수 가 늘어나면, 비트가 더 필요로한다. 여기 25Mhz 클럭과 16비트 Acc가 있다.
parameter ClkFrequency = 25000000; // 25Mhz
parameter Baud = 115200;
parameter BaudGeneratorAccWidth = 16;
parameter BaudGeneratorInc = (Baud<<BaudGeneratorAccWidth)/ClkFrequency;
reg [BaudGeneratorAccWidth:0] BaudGeneratorAcc;
always @(posedge clk)
BaudGeneratorAcc <= BaudGeneratorAcc[BaudGeneratorAccWidth-1:0] + BaudGeneratorInc;
wire BaudTick = BaudGeneratorAcc[BaudGerneratorAccWidth];
BaudGerneratorInc계산이 틀리는데, 이는 Verilog가 32비트를 쓰지만, 계산이 그것을 초과해서 생긴다. 따라서, 다음과 같이 바꾼다.
parameter BaudGeneratorInc = ((Baud<<(BaudGeneratorAccWidth-4))+(ClkFrequency>>5))/(ClkFrequency>>4);
이렇게 하면, 끝수를 버리지 않는 결과값을 가질수 있는 이점이 있다.
다음은 RS-232 트랜스미터 모듈이다. 여기를 클릭하라