해결된 질문
작성
·
1K
0
페이지 156쪽에 대한 질문입니다.
scl신호를 생성하기 위한 카운터와 scl 반주기 counter 두개를 설계하신 이유가 궁금합니다. 아무리 읽어봐도 잘 이해가 안가서요 ㅠㅠ.. 그리고 3-1) start_runw부분을 한번만 더 자세하게 설명해주실수 있을까요?
답변 1
0
아래 그림을 참조하세요.
srw_cnt1은 SCL 반주기를 만들기 위한 카운터이고, srw_cnt2는 SCL 반주기를 카운트 하는 카운터입니다. (그림의 녹색부분의 숫자가 srw_cnt2 입니다)
srw_done, scl_o, sda_o 신호들이 srw_cnt1, srw_cnt2의 값으로 생성됩니다.
verilog는 모든 신호들이 main clock(mclk)에 동기 되어 생성됩니다. srw_cnt2 값은 SCL 반주기 동안에는 같은 값을 유지하고, srw_cnt1은 mclk 마다 값이 바뀝니다. srw_done, scl_o, sda_o 신호들은 mclk의 특정한 한 순간에 값이 바뀌고 나머지 구간에서는 그 값을 유지하게 하기 위해서, srw_cnt1, srw_cnt2의 값들의 조합으로 생성되게 됩니다.
코드 중에, (srw_cnt1==SDAO_POS) 이 들어간 이유는 SCL의 Rising, Falling Edge에서 바로 데이터를 수신하지 않고, 몇 clock 지난 후에(안정적으로 데이터를 얻기 위하여) 수신하기 위하여 추가되었습니다.
위 그림을 보면서 이해하면 이해가 쉽습니다.
1) srw_done : 라인 98
srw_cnt2가 20일 때, srw 상태가 완료됩니다.
따라서, ((srw_cnt2==5'd20) && (srw_cnt1==SDAO_POS)) 일 때 Active 됩니다.
2) scl_o : 라인 240
원래는 srw_cnt2의 값에 따라서 0, 1 로 만들어 주어야 하는데, ~srw_cnt2[0]로 생성해도 됩니다.
이 부분은 simulation으로 직접 확인해 보세요.
3) sda_o : 라인 254-263
srw_cnt2의 값에 따라서 data_w의 값을 bit[7] ~ bit[0]까지 전송합니다.
4) err_ack : 라인 339
slave에서 ack 신호를 정상적으로 보내었는지를 확인합니다.
ack가 정상적으로 수신되면 0, ack 가 수신되지 않으면 1 입니다.
5) busy : 라인 350 - 351
각 상태에서 데이터 전송중인지, 각 상태가 완료되었는지를 나타냅니다.
상위 모듈에서 사용하는 신호입니다.
busy 신호 대신 done 신호를 사용해도 됩니다.
verilog는 눈으로 봐서는 이해가 어렵습니다. 직접 simulation을 통하여 확인하셔야 됩니다. 소스중에 Test bench도 함께 있으니 반드시 simulation으로 확인해 보셔야 합니다. 어느 순간에 done 신호가 Active 되고 그 다음에 또 어떤 신호가 Active 되고 이러한 과정은 simulation을 통하여만 확인할 수 있습니다.
저도 개발 경력이 20년이 넘지만, i2c master 설계하기 위해서 수십 번도 넘게 simulation 하며 확인하고 코드 수정하고 그러한 과정을 거치며 코딩을 합니다.
아무쪼록 verilog를 배우시기로 작정하셨다면 힘들고 어렵더라고 직접 simulation으로 검증하며 배우시길 바랍니다.
감사합니다.
네 자세하게 설명해주셔 감사합니다!