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

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

작성한 질문수

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

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

delay 질문.

해결된 질문

21.09.02 01:24 작성

·

592

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

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

2021. 09. 03. 10:06

안녕하세요 :)

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

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

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

https://inf.run/MqnQ

즐공하세요 :)

1

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

2021. 09. 03. 00:59

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

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

2021. 09. 02. 10:36

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

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 시키려면 어떻게 코드를 수정해야하죠?!

답글로 꼭 남겨주세요.

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

2021. 09. 02. 10:52

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

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

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

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

2021. 09. 02. 11:11

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

1. clean 하고 다시해보기.

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

맞춰서 돌려볼께요.

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

2021. 09. 02. 11:19

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

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

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

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

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

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

2021. 09. 02. 11:27

아하 넵!

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

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

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

2021. 09. 02. 11:32

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

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

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

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

2021. 09. 02. 12:05

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

코드로 올려주세요 :)

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

2021. 09. 02. 13:40

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로 출력되었습니다.

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

2021. 09. 02. 14:17

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

(

검사 겸.. 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 하고 같이 올려주세요.

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

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

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

2021. 09. 02. 14:43

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

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

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

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

2021. 09. 02. 15:21

화이팅 입니다!

1

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

2021. 09. 02. 08:01

음...

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

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

r_valid 를 wire 로 바꿔볼까요?

wire r_valid = i_valid;

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

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

즐공하세요 :)

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

2021. 09. 02. 10:28

감사합니다 맛비님!

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

현재 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 가 선언되어 있지 않다고 오류가 뜹니다..