https://chanfifo77.tistory.com/86

 

[Verilog] 20. SPI Debugging(1)

발견된 문제점1. 전제 모듈 연결 후, Read 할 때, MISO 값이 간헐적으로 이상하게 나오는 것을 확인.2. Master에서 RX FIFO로 가는 DOUT의 출력 값 이상 확인.3. Master DIN이 값을 가져오는 주기의 이상 확인.

chanfifo77.tistory.com

저번 포스팅에 이어 작성하겠습니다.

 

먼저 추가적인 문제점 발견하여 부분 수정 후 다시 Synthesis 진행 예정.

1) FIFO RX에서 DOUT이 간헐적으로 출력되는 것을 확인.

 

발견한 원인

WR, RD 신호가 정상적으로 인식되지 않음.

1. 읽으려는 신호가 없는데 읽음

2. spi.test의 cnt에 따라서 fifo의 address에 저장하는 방식으로 사용하였지만. cnt가 0이 아닐때 rd가 동작하면 이상한 위치에 읽고 값이 밀려써지는 현상이 발생하는 것 확인.

 

해결과정.


1. spi_master 수정

always @ (negedge CLK) begin
    if(phase == 0 && bit_cnt == 0)
        DOUT <= shift_reg;
    if(phase == 0 && bit_cnt == 1 && clk_cnt == 6 && (DOUT == shift_reg) && DOUT != 0)
        wr <= 1'b1;
    if(phase == 0 && bit_cnt == 1 && clk_cnt == 7 && (DOUT == shift_reg) && DOUT != 0)
        wr <= 1'b0;
end

기존에 FSM내에 있던 WR를 분리하여 다른 블록에서 사용

기존 DOUT <= shift_reg 는 phase의 negedge마다 동작하도록 구현하였지만,

DOUT이 전달된 직후 wr가 동작하도록 수정. 그 후 1 clk 뒤에 바로 off 되게 설정.


2. spi_test 수정.

always @ (posedge CLK) begin
    if(state == idle)
        wr_cnt <= 0;
    else if(wr)
        wr_cnt <= wr_cnt + 1;
end

wr_cnt라는 신호를 새로 만들어서.

wr되는 값마다 바로바로 read 할 수 있게 수정.

data_rd - state의 idle 조건을 cnt == wr_cnt로 변경.


3. spi_slave 수정.

        RD_WR : begin
        //initialize state
                if (phase && bit_cnt == 8)
                    state <= IDLE;
                else begin  
        //RD
                if(phase && cmd && bit_cnt != 0)
                    MISO <= rd_data[7 - bit_cnt];
                else
                    MISO <= 1'b0;

기존 RD 부분에서 조건문은

if (phase && cmd)였기 때문에 2페이즈 첫 SCLK에 값을 읽어오면 저번 rd_data의 최상위 비트를 함께 읽어오는 오류가 발생하였기 때문에 값을 읽는 주기를 1 SCLK 늦춰주었다.

 


+)

integer i;
initial begin
    for(i =0; i < 32; i = i + 1)
        ram[i] = 8'b0;
end

rx_fifo에서 ram의 초기값을 모두 0으로 설정

 

기존 있었던 Implementation / Generate Bitstream 문제는 Board 연결 시 핀 할당에 대한 문제라고 한다.

Linter Schematic

 

Simulation Pulse of SPI

 

이로써 수정된 SPI는 정상적으로 Synthesis 까지 정상적으로 동작됨.