인프런 커뮤니티 질문&답변
맛비님 데이터를 딜레이 시키는 구문에 대해 질문이 있습니다.
작성
·
346
1
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요!
- 먼저 유사한 질문이 있었는지 검색해보세요.
- 서로 예의를 지키며 존중하는 문화를 만들어가요.
- 잠깐! 인프런 서비스 운영 관련 문의는 1: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
에 출력될 것이라는 의미 같은데요.
역시 이것도 왜 그렇게 되는지 이해가 안갑니다. ㅠㅠ
(추천해 주신 책은 열심히 읽고 있습니다 ㅠㅠ, 아직 내공이 부족하네요.)
퀴즈
FPGA 기반 하드웨어 가속기 설계에서 Data Mover BRAM 모듈의 주된 역할은 무엇일까요?
CPU가 복잡한 알고리즘을 효율적으로 실행하도록 돕습니다.
FPGA 내부의 두 BRAM 메모리 간에 데이터를 효과적으로 전송합니다.
소프트웨어 코드를 하드웨어 명령으로 변환하는 역할을 합니다.
FPGA 칩의 전력 소모량을 줄여줍니다.
답변 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 코드에 버그가 있어요.
다음글도 참고하시면, 도움이 되실꺼에요.





