강의

멘토링

로드맵

Inflearn brand logo image

인프런 커뮤니티 질문&답변

choisi님의 프로필 이미지
choisi

작성한 질문수

설계독학맛비's 실전 FPGA를 이용한 HW 가속기 설계 (LED 제어부터 Fully Connected Layer 가속기 설계까지)

[FPGA 15장] FSM 을 이용한 BRAM Data Mover 모듈 설계 - 코드리뷰편

맛비님 데이터를 딜레이 시키는 구문에 대해 질문이 있습니다.

작성

·

330

1

- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요.
 
dat_mover_bram.v 파일에서
 
1.
// Shift Delay
always @(posedge clk or negedge reset_n) begin
    if(!reset_n) begin
        r_core_delay <= 0;  
    end else begin
        r_core_delay <= {r_core_delay[CORE_DELAY-2:0], r_valid}; // read data
    end
end
해당 구문이 shift register가 된다는 사실은 알겠습니다.
허나 이 구문이 왜 딜레이 되는 타이밍과 관계 있는지 모르 겠습니다.
assign ce_b1    = r_core_delay[CORE_DELAY-1];
assign we_b1    = r_core_delay[CORE_DELAY-1];
결국 chip enable과 write enable을 r_core_delay[4]->행렬의 MSB의 값으로 입력된다는 의미인거 같은데요.
여기서 r_valid 값은 LSB인거 같은데요. 어떤 메커니즘으로 최상위 비트가 되는 건지 모르겠습니다.
 
2.
// Shift Data
genvar  idx;
generate
    for (idx = 0; idx < CORE_DELAY-1; idx = idx + 1) begin : gen_core_delay
        always @(posedge clk or negedge reset_n) begin
            if(!reset_n) begin
                r_core_data[idx+1]   <= {DWIDTH{1'b0}};
            end else if(|r_core_delay) begin
                r_core_data[idx+1]   <= r_core_data[idx];
            end
        end
    end
endgenerate

// first one
always @(posedge clk or negedge reset_n) begin
    if(!reset_n) begin
        r_core_data[0] <= {DWIDTH{1'b0}};  
    end else if(|r_core_delay) begin
        r_core_data[0]  <= mem_data; // read data
    end
end
해당 구문에서 결국 의미 하는 것은
r_core_data[0]  <= mem_data;
                r_core_data[1]   <= r_core_data[0];
                r_core_data[2]   <= r_core_data[1];
                r_core_data[3]   <= r_core_data[2];
                r_core_data[4]   <= r_core_data[3];
일 텐데요.
말씀하시는 내용은 결국 알맞은 타이밍에 mem_data가 최상위 비트까지 올라가서 해당 테이터가 결국
assign d_b1     = r_core_data[CORE_DELAY-1];  // core value
에 출력될 것이라는 의미 같은데요.
역시 이것도 왜 그렇게 되는지 이해가 안갑니다. ㅠㅠ
(추천해 주신 책은 열심히 읽고 있습니다 ㅠㅠ, 아직 내공이 부족하네요.)
 
 
 
 
 
 
 
 
 
 
 
 

답변 1

0

설계독학맛비님의 프로필 이미지
설계독학맛비
지식공유자

안녕하세요 :)

1.
// Shift Delay
always @(posedge clk or negedge reset_n) begin
    if(!reset_n) begin
        r_core_delay <= 0;  
    end else begin
        r_core_delay <= {r_core_delay[CORE_DELAY-2:0], r_valid}; // read data
    end
end
해당 구문이 shift register가 된다는 사실은 알겠습니다.
허나 이 구문이 왜 딜레이 되는 타이밍과 관계 있는지 모르 겠습니다.
assign ce_b1    = r_core_delay[CORE_DELAY-1];
assign we_b1    = r_core_delay[CORE_DELAY-1];
결국 chip enable과 write enable을 r_core_delay[4]->행렬의 MSB의 값으로 입력된다는 의미인거 같은데요.
여기서 r_valid 값은 LSB인거 같은데요. 어떤 메커니즘으로 최상위 비트가 되는 건지 모르겠습니다.
 
매커니즘은 코드에 기술이 되어 있어서 말로 설명이 어렵네요 ㅠ (코드가 말보다 명확하니까.. 천천히보시면 이해가 되실거에요.)
"Shift Register 를 통해서 CORE_DELAY Cycle 만큼 Delay 시켰습니다."
이 설명이 이해가 잘 안되신다면, Waveform 을 띄우신 후에,
"r_valid" 와, "r_core_delay[4] " 의 Signal 을 확인해보세요.
그래도 이해가 안되신다면, 제가 질문을 잘못이해한 것일 수 있어요. (사람인지라 ㅠ)
상세히 설명해 주시면 답변에 도움이 될 것 같아요.
 
 
2.
// Shift Data
genvar  idx;
generate
    for (idx = 0; idx < CORE_DELAY-1; idx = idx + 1) begin : gen_core_delay
        always @(posedge clk or negedge reset_n) begin
            if(!reset_n) begin
                r_core_data[idx+1]   <= {DWIDTH{1'b0}};
            end else if(|r_core_delay) begin
                r_core_data[idx+1]   <= r_core_data[idx];
            end
        end
    end
endgenerate

// first one
always @(posedge clk or negedge reset_n) begin
    if(!reset_n) begin
        r_core_data[0] <= {DWIDTH{1'b0}};  
    end else if(|r_core_delay) begin
        r_core_data[0]  <= mem_data; // read data
    end
end
해당 구문에서 결국 의미 하는 것은
r_core_data[0]  <= mem_data;
                r_core_data[1]   <= r_core_data[0];
                r_core_data[2]   <= r_core_data[1];
                r_core_data[3]   <= r_core_data[2];
                r_core_data[4]   <= r_core_data[3];
일 텐데요.
말씀하시는 내용은 결국 알맞은 타이밍에 mem_data가 최상위 비트까지 올라가서 해당 테이터가 결국
assign d_b1     = r_core_data[CORE_DELAY-1];  // core value
에 출력될 것이라는 의미 같은데요.
역시 이것도 왜 그렇게 되는지 이해가 안갑니다. ㅠㅠ
(추천해 주신 책은 열심히 읽고 있습니다 ㅠㅠ, 아직 내공이 부족하네요.)
 
말씀해주신대로, Generate 를 통해서 r_core_data 가 assign 되구요.
이것도 위의 설명과 같은 논리 입니다.
Waveform 을 띄우셔서
r_core_data[4] 에 해당하는 Value 와, mem_data 이렇게 두개의 값을 비교해보세요. (Timing 을 보세요. Delay 가 얼만큼 되는지.)
 
확인부탁드려요 :)
 
Ps. 이 질문과는 관련 없지만 15장의 data_mover 코드에 버그가 있어요.
다음글도 참고하시면, 도움이 되실꺼에요.
 
 
choisi님의 프로필 이미지
choisi

작성한 질문수

질문하기