해결된 질문
작성
·
9
0
안녕하세요, 시뮬레이션 결과를 보던 중 이해가 잘 안가는게 있어서 질문드립니다!
여기서 W_CRC는 제가 이해하기로는 '나머지' 에 대응되는 코드로, 나머지가 '0' 이면 오류가 없는 것이고, 나머지가 '0' 이 아니라면 오류가 있음을 알리는 코드로 알고 있습니다. 근데 시뮬레이션 결과를 보면 각 입력 데이터 r_data에 대응되어서 모두 0이 아닌 다른 값으로 update 되는데 그러면 CRC 오류가 있어서 저런 결과가 나오는거로 이해하면 될까요?? 감사합니다!
답변 1
0
안녕하세요, 답변 남겨드립니다.
CRC 연산에서 W_CRC
값이 어떻게 변화하는지 더 깊게 설명드리겠습니다. 질문 주신 부분은 CRC의 중간 과정과 최종 결과의 차이를 정확히 이해하셔야 혼동이 없으실 것 같습니다.
먼저 CRC는 다항식 나눗셈에 기반한 연산으로, 전송 데이터 D(x)를 미리 정의된 생성다항식 G(x)로 나눈 나머지를 구하는 과정입니다. 이때 중요한 점은 실제 하드웨어나 시뮬레이션에서 CRC는 단순히 한 번에 나눗셈을 하는 것이 아니라, 데이터 비트를 순차적으로 입력받으면서 shift register와 XOR 연산을 통해 W_CRC를 매 사이클마다 갱신한다는 것입니다.
예를 들어 8비트 데이터 r_data = 10110011
을 CRC-4-ITU (G(x) = x^4 + x + 1)로 연산한다고 가정해 보겠습니다.
초기 CRC 레지스터 값을 0000
으로 세팅합니다.
첫 번째 입력 비트 ‘1’을 넣으면, CRC 레지스터는 G(x)에 따라 XOR 및 시프트되어 1001
이 됩니다.
두 번째 입력 비트 ‘0’을 넣으면, 다시 XOR/Shift가 일어나 CRC 값이 0010
으로 갱신됩니다.
이런 식으로 모든 8비트를 넣는 동안 CRC 레지스터(W_CRC)는 1001 → 0010 → 1111 → 0101 …
처럼 계속 변화합니다.
이 과정을 거쳐 마지막 비트까지 입력한 후에 나온 최종 W_CRC 값이 바로 데이터에 대한 CRC 결과입니다. 이 최종 결과가 0000
이면 데이터가 오류 없이 정상적으로 수신된 것이고, 0000
이 아니라면 전송 도중 오류가 발생했다고 판단합니다.
따라서 질문 주신 시뮬레이션에서 보신 것처럼 r_data
가 들어올 때마다 W_CRC가 매번 갱신되어 0이 아닌 값이 나오는 것은 정상적인 과정입니다. 오히려 모든 비트가 들어오기 전에 항상 0이 나왔다면, CRC 로직이 잘못 설계된 것이라고 볼 수 있습니다.
현업 사례를 들어 설명드리면, NAND Flash 메모리나 SSD 컨트롤러에서 데이터 전송 시 CRC를 사용합니다. 예를 들어 2KB 페이지 데이터를 전송한다고 하면, 컨트롤러는 2KB 데이터를 순차적으로 CRC 회로에 입력하면서 내부의 W_CRC 값을 계속 업데이트합니다. 이 중간 값들은 검증 대상이 아니며, 마지막 바이트까지 다 넣은 뒤의 W_CRC 값이 최종적으로 0인지 여부를 가지고 오류 검출을 수행합니다.
즉, 지금 시뮬레이션 결과에서 W_CRC가 매번 0이 아닌 이유는 단순히 CRC 연산의 중간 단계이기 때문이며, 이것을 곧바로 오류로 해석하면 안 됩니다. 반드시 데이터 스트림 전체를 넣은 후의 최종 W_CRC 값을 확인하셔야 오류 여부를 판별할 수 있습니다.
추가적으로, 만약 디버깅 목적으로 확인하고 싶으시다면 Testbench에서 마지막 입력 데이터가 들어간 후 몇 클럭이 지난 시점의 W_CRC 레지스터 값을 출력하도록 설정해 보시면 정확히 “최종 CRC 값”만 확인할 수 있습니다. 예를 들어 Verilog Testbench라면 아래와 같이 체크할 수 있습니다.
@(posedge last_data_in); // 마지막 데이터 입력 시점
#1 $display("Final CRC = %h", W_CRC);
이렇게 하면 중간 update 값이 아니라 최종 결과만 관찰할 수 있어서, 현재 시뮬레이션에서 헷갈리셨던 부분이 해소되실 겁니다.