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

지루한 까치님의 프로필 이미지
지루한 까치

작성한 질문수

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

[FPGA 21장] 프로젝트 Fully Connected Layer 설계 - 코드리뷰편

delay 질문.

해결된 질문

작성

·

619

1

안녕하세요 맛비님!

뭔가 재 질문하게 되는거 같아 죄송합니다..

r_vaild 신호를 이용해서 delay가 되는 원리가 이해가 되지 않습니다..

always @(posedge clk or negedge reset_n) begin

 if(!reset_n) begin

   r_vaild <= 1'b0;

  end else if (i_run) begin

   r_vaild <= 1'b0;

  end else begin

   r_vaild <= i_vaild;

 end

end

이 구문에서 i_vaild 라는 저장공간에 있는 값을 r_vaild 라는 저장공간으로 이동하게 되면 delay가 발생하는 원리가 맞나요??  즉, 저장공간에서 저장공간으로 값이 이동하게 되면 delay 가 생긴다.. 제대로 이해한게 맞을까요??

답변 4

1

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

안녕하세요 :)

올려주신 코드에서, F/F 이 delay 를 만듭니다. 다음 그림에서, 파란색으로 색칠한거!

회로를 그려보면 더욱 이해가 잘 되실꺼구요.

그리는 방법은, 다음 링크의 제 답변을 참고해주세요.

https://inf.run/MqnQ

즐공하세요 :)

1

s간단한 코드부터 다시 시작하며 공부하고 있습니다.

 왠지 지금 이 발견이 shift reg 에 좀 더 다가갈 수 있는 길이라고 생각해서 질문드립니다!

* testbench

`timescale 1ns / 1ps

module tb_shift_reg_exam;

reg clk;

reg reset_n;

reg [6:0] tb_value;

always

 #5 clk = ~clk;

integer i;

initial begin

reset_n = 1;

clk = 0;

tb_value = 0;

#5

reset_n = 0;

#5

reset_n = 1;

#5

//@(posedge clk)

for(i=1;i<101;i=i+1) begin

@(posedge clk);

tb_value = i;

end

#10 

$finish;

end

shift_reg_exam DUT(

.clk(clk),

.reset_n(reset_n),

.value(tb_value)

);

endmodule

* DUT

`timescale 1ns / 1ps

module shift_reg_exam(

input clk,

input reset_n,

input [6:0] value,

output [12:0] sum

);

reg  [12:0] r_sum;

wire [12:0] w_sum;

always @(posedge clk  or negedge reset_n) begin

if(!reset_n) begin

r_sum <= 0; 

end else begin

r_sum <= w_sum;

end

end

//assign sum = sum + value;

assign w_sum = r_sum + value;

assign sum = w_sum;

endmodule

맛비님께서 만드신 build 파일 수정해서 시뮬레이션 돌렸습니다.

열심히 공부해보겠습니다. 감사합니다.

궁금한 점은 현재 저의 코드 어느 부분에서 r_sum 값이 delay 되게 만드는지 궁금합니다!!

1

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

이걸로 해보시겠어요? (백문이 불여코드죠?)

r_valid 의 차이를 확인하시면 됩니다.

제가 지금 올려드린 코드에서는 145ns 에 올라갔죠? 이제 "공유드린 원래 코드" 를 돌려보시고 차이점을 설명해보세요. 

생? 으로 올려드립니다.

//////////////////////////////////////////////////////////////////////////////////

// Company: Personal

// Engineer: Matbi / Austin

//

// Create Date: 2021.01.31

// Design Name: 

// Module Name: fully_connected_core_8b

// Project Name:

// Target Devices:

// Tool Versions:

// Description: To study ctrl sram. (WRITE / READ)

// FSM + mem I/F

// Dependencies:

//

// Revision:

// Revision 0.01 - File Created

// Additional Comments:

//

//////////////////////////////////////////////////////////////////////////////////

 

`timescale 1ns / 1ps

module fully_connected_core

// Param

#(

parameter IN_DATA_WITDH = 8

)

(

    input clk,

    input reset_n,

input i_run,

input i_valid,

input [IN_DATA_WITDH-1:0] i_node,

input [IN_DATA_WITDH-1:0] i_wegt,

output  o_valid,

output  [(4*IN_DATA_WITDH)-1:0] o_result

);

// 1 cycle delay

//reg r_valid;

wire r_valid;

reg [(4*IN_DATA_WITDH)-1:0] r_result;

wire  [(2*IN_DATA_WITDH)-1:0] w_result;

//always @(posedge clk or negedge reset_n) begin

//    if(!reset_n) begin

//        r_valid <= 1'b0;  

//    end else if (i_run) begin

//        r_valid <= 1'b0;  

//    end else begin

// r_valid <= i_valid;

// end

//end

assign r_valid = i_valid;

always @(posedge clk or negedge reset_n) begin

    if(!reset_n) begin

        r_result <= {(4*IN_DATA_WITDH){1'b0}};  

    end else if (i_run) begin

        r_result <= {(4*IN_DATA_WITDH){1'b0}};  

    end else if (i_valid) begin  // valid == enable.

r_result <= r_result + w_result; // accum

end

end

assign o_valid = r_valid;

assign w_result = i_node * i_wegt;

assign o_result = r_result;

endmodule

시작한 김에 올려드립니다. (공유드린 original code 결과)  자 어떤가요?!!!!!!!!!!!!!!

완벽하게 이해하시라고 문제드립니다.

r_valid 를 2 cycle delay 시키려면 어떻게 코드를 수정해야하죠?!

답글로 꼭 남겨주세요.

코드를 수정하는 방법은 얼추 알아서 수정해서 올려보겠습니다!!

맛비님께서 올려주신 코드로 수정해서 돌려서 시뮬레이션 보려고 했는데 동작이 안되서 올려드립니다..

제가 뭐를 빼먹었을까요??

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

음? 확인하고 올려드린건데..

1. clean 하고 다시해보기.

2. 사용하고 있는 Tool version 을 알려주세요.

맞춰서 돌려볼께요.

원래 코드로 돌리면 정상정으로 gui 실행 후 시뮬레이션도 실행됩니다.. 흠 뭐가 오류이지

clean 후 실행했는데 같은 현상이 반복됩니다. 아예 종료했다가 다시 해보겠습니다.

현재 사용하는 버전은 2021.01 버전 입니다!

-------------------------------------

아아 맛비님 오타가 있었습니다. 최송합니다. 오류 수정하니 동작 정상적으로 됩니다!!

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

아하 넵!

2 cycle delay 코드는 안올려주셔도 돼요. 

이해하신 것? 같아보입니다. ㅎ

검사 겸.. delay 원리만 올려보겠습니다!

n 만큼 delay 를 위해서는 저장공간(reg)를 이용하면 되므로 현재 한 공간으로 정해진 공간은 배열을 이용해서 

공간을 원하는 만큼 만들어주고 반복문을 사용해서 돌려주면 되지 않을까 싶습니다.. 맞을까요??

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

저의 정확한 답변을 듣고 싶다면, 방금 이야기를...

코드로 올려주세요 :)

2 delay 하는 방법을 생각해봤습니다!

reg [1:0] r_vaild;

always @(posedge clk or negedge reset_n) begin

 if(!reset_n) begin

   r_vaild <= 2'b00;

  end else if (i_run) begin

   r_vaild <= 2'b00;

  end else begin

   r_vaild <= {r_valid[1:0], i_vaild} ;

 end

end

------------------------------------------

다음은 15장의 delay 구문을 참고해서 해보려고 했는데 뭔가 잘 되지 않습니다.

근데 궁금증이 또 생겨버렸습니다. 구글링을 열심히 해봤는데 이해가 되지 않습니다.

reg [4:0] r_core_delay;

reg r_vaild = 1;

r_core_delay <= {r_core_delay[3:0], r_valid};

이라고 코드가 있을 때 병합 내부에 다음과 같이 배열이 있으면 어떻게 진행이 되는건지 궁금합니다.

갑자기 선언문에는 배열이 없다가 생긴 것도 이상하고

예를들어 r_core_delay[0] = 00000 , r_valid = 1 이면 병합구문이기 때문에 000001이 맞지 않나 생각도 되는데.. 머릿속이 꼬인거 같습니다..

시뮬레이션 결과는 r_valid = 1 이 되었을 때 r_core_delay 의 width는 5bit 이기 때문에 11111로 출력되었습니다.

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

길게 적어보겠습니다. (잘 따라 오셨다라고 생각했는데, 약간의 실망? 을 했습니다. 제 불찰입니다.) 친절하게 적지 못한 점 미리 양해 부탁드립니다.

(

검사 겸.. delay 원리만 올려보겠습니다!

n 만큼 delay 를 위해서는 저장공간(reg)를 이용하면 되므로 현재 한 공간으로 정해진 공간은 배열을 이용해서 

공간을 원하는 만큼 만들어주고 반복문을 사용해서 돌려주면 되지 않을까 싶습니다.. 맞을까요??

문장으로 했던  원하는 결과가 나오나요? )

코드 첨삭 드립니다.

이 코드를 보면서 느낀건.. Verilog HDL 책을 통해 문법하고, 기본 HW 개념을, 별도로 공부해야 한다는 생각이 먼저드네요. 이 책 보신적 있으신가요?

그 다음 제 강의를 보시는게 좋아보입니다.

2 delay 하는 방법을 생각해봤습니다!

reg [1:0] r_vaild;

always @(posedge clk or negedge reset_n) begin

 if(!reset_n) begin

   r_vaild <= 2'b00;

  end else if (i_run) begin

   r_vaild <= 2'b01;  // 왜 01 이죠?

  end else begin

   r_vaild <= i_vaild ;   

   r_vaild <= r_valid + 1;  // counter 인가요..? 

// r_valid 에 assign 이 두개 인데, 이게 HW 적으로 어떻게 그려지죠?

// 독하게 말씀드리면, 책을 보라고 한 이유가 있습니다. 제 영상을 보는 것 보다, 기본이 우선이 되어야 할 것 같아요.

 end

end

지금부터는.  제가 정답을 안 드릴겁니다. 저만 이해하는 느낌입니다.

'나' 님께서 직접 이해하셔야 합니다.

솔루션 드립니다.

shift register 를 다시 공부하실 필요가 있습니다.

shift register 부터, 제 코드 보지마시고, 본인이 직접 설계해보세요.

Testbench 도 설계해보시구요. 직접 돌려보세요. 눈으로 보세요. 이해하세요.

======================================================

다음은 15장의 delay 구문을 참고해서 해보려고 했는데 뭔가 잘 되지 않습니다.

근데 궁금증이 또 생겨버렸습니다. 구글링을 열심히 해봤는데 이해가 되지 않습니다.

reg  [4:0] r_core_delay;

reg r_vaild = 1;

r_core_delay <= {r_core_delay[3:0], r_valid};

이라고 코드가 있을 때 병합 내부에 다음과 같이 배열이 있으면 어떻게 진행이 되는건지 궁금합니다.

갑자기 선언문에는 배열이 없다가 생긴 것도 이상하고

예를들어 r_core_delay[0] = 00000 , r_valid = 1 이면 병합구문이기 때문에 000001이 맞지 않나 생각도 되는데.. 머릿속이 꼬인거 같습니다..

시뮬레이션 결과는 r_valid = 1 이 되었을 때 r_core_delay 의 width는 5bit 이기 때문에 11111로 출력되었습니다.

먼저 concat 은 저번에 저한테 물어보신거, 링크 달아드립니다.

https://inf.run/gnLn

자......  천천히 생각해보세요.... 급하게 할 것 없습니다.... 급하면 얻는게 없어요.

충분히 고민해보셨나요? 돌려보셨나요? 

이미 코드를 올리셨고, 직접 돌려서 waveform 을 보세요. 그러면 답을 찾을 수 있습니다. (현재 그런 상황이라서 이 말을 쓰구요. 이정도는 충분히 하실 수 있다 판단 됩니다.)

그래야 자기 것이 됩니다.

올려주신 코드가, 지금 이 긴문장의 트리거가 되었습니다.

이해하셨다고 믿고 있었는데.. 아니라서 적은겁니다.

다소 독하게 적었습니다. 꼭 이겨내시리라 믿습니다.

포기하지 마시고, Step by Step 입니다. Verilog HDL 부터 돌아가죠.

결론 : 기본기를 더 쌓으셨으면 좋겠습니다, 그리고 직접 돌려보셨으면 좋겠습니다.

그리고 제가 내드린 과제, 직접 Shift register 설계하셔서 waveform 하고 같이 올려주세요.

'나' 님의 근성? 정성? 이면 충분히 깨달음이 있을 거라 생각합니다.

단지 수 많은 과정 중 사소한 하나입니다. 포기하지 마세요. 즐공입니다 :)

네 맞습니다.. 파란 책은 구매해서 같이 보면서 이해하고 있습니다!!

무작정 진도만 나가려고 했던 저의 실수였습니다!

과제 완수하고 돌아오겠습니다! 감사합니다.

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

화이팅 입니다!

1

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

음...

1cycle delay 를 이해하기 가장 좋은 방법, 직접 해보기.

지금처럼 하시면 r_valid 는 ff 이죠?

r_valid 를 wire 로 바꿔볼까요?

wire r_valid = i_valid;

이렇게 하셔서 waveform 으로 r_valid 의 신호를 캡쳐해서 올려주세요.

자... 똑같나요? 다른가요? 다르다면 어떻게 다르죠?

즐공하세요 :)

감사합니다 맛비님!

해당 내용을 실행하려다 보니 많은 오류가 떠서 해결하려고 코드를 바꿔보고 했는데 잘 안되네요.. 

현재 r_vaild는 reg 로 선언 되어 있는 상태에서 wire로 변경하면

always @(posedge clk or negedge reset_n) begin

 if(!reset_n) begin

   r_vaild <= 1'b0;

  end else if (i_run) begin

   r_vaild <= 1'b0;

  end else begin

   r_vaild <= i_vaild;

 end

end

if 문 내부에 있는 <= 값을 저장하는 이 구문은 사용하지 못할 것으로 판단해서 = 으로 변경했습니다.

하지만 left hand side 오류가 떠서 확인해보니 wire 와 같은 net 타입은 assign 을 통해 연결해줘야 한다고 했고 그럼 always 구문을 모두 주석처리하고 assign을 해주자 하니 i_valid 가 선언되어 있지 않다고 오류가 뜹니다..

지루한 까치님의 프로필 이미지
지루한 까치

작성한 질문수

질문하기