작성
·
857
1
안녕하세요 맛비님
BRAM의 데이터를 Read할 때 Testbench에서 address를 1씩 증가시켜서 읽어보면 address와 read data가 동클락에 나오는 걸 방지하기 위해 r_valid로 1 cycle delay 시켜주는 것으로 이해했습니다.
하지만 주소를 생성하는 모듈 ((ex) address를 0부터 15까지 1씩 증가하면서 BRAM에 address를 보내주는 모듈) 과 BRAM을 연결해 Testbench에서 address를 1씩 증가시키지 않고 알아서 address를 BRAM으로 보내주어 시뮬레이션을 돌려보니,
r_valid가 존재하지 않아도 read할 때 자동으로 1 cycle delay 미뤄줍니다. 이 이유를 혹시 아실까요?
답변 2
0
그 부분은 이해했습니다 감사합니다.
`timescale 1ns / 1ps
module sram_16x8(addr, clk, din, dout, we);
parameter addr_width = 4, word_depth = 16, word_width = 8;
input [addr_width-1:0] addr ;
input [word_width-1:0] din ;
output [word_width-1:0] dout ;
input clk, we ;
reg [word_width-1:0] mem [0:word_depth-1];
reg [word_width-1:0] dout;
//Write
always @(posedge clk) begin
if(!we)
mem[addr] <= din[word_width-1:0];
end
//Read
always @(posedge clk) begin
if(we)
dout <= mem[addr]; end endmodule
하지만 위와 같이 dut를 설계했을 때,
위의 코드대로라면, ①에서 addr의 1과 we의 1을 채고, 이를 기반으로 ②구간에 dout이 mem[1] = 1
이여야한다고 생각했지만, ②구간에 dout이 mem[0] = 0이 나왔습니다.
read를 할 때는 clock에 동기화돼서 나타나야한다고 생각하는데 왜 async 처럼 동작하는지 잘 모르겠습니다.
ps) 다른 dut 생성을 하지 않고, address는 아래와 같이 testbench에서 직접 넣어주었습니다.
@(posedge clk); addr = 0;
@(posedge clk); addr = 1;
@(posedge clk); addr = 2;
@(posedge clk); addr = 3;
@(posedge clk); addr = 4;
넵 죄송합니다. 그러면
true_dpbram 코드만 따로 발췌하여 address를 testbench로 지정해줬을 때는 read시 addr0 이 입력된 다음 cycle 에 출력이 되지않고, 동일 사이클에 출력이 되지만,
address를 다른 모듈로부터 받아오면 read시 aaddr0 이 입력된 다음 cycle 에 출력되는 이유를 아실까요?
현상만 보았을때 Testbench 에서 "Clock 에 동기화 되지 않은 코딩"을 하고 계신것이 아닌가 예측을 해봅니다. 다음 링크가 도움이 되실 것 같아요. :)
맛비님.. 정확합니다!!
저도 이 현상때문에 골머리를 앓고 똑같은 블로그를 참고했었습니다.
즉, 의도는 CLK이 한번 올라간(no.1 clock edge) 다음 push를 1'b1로 올리고자 하였을지라도
이 구문에서는 push가 1'b1, wdata가 data로 올라가 있는 상태에서 CLK이 올라가는(no.1 clock edge) 상황으로 인지하게 된다.
출처: https://sunshowers.tistory.com/9 [Sunshowers:티스토리]
혹시 이런 현상을 지칭하는 영단어가 있을까요? (ex) verilog race condition..
위와 같은 현상은 RTL simulation 오류인가요? 아니면 의도된(당연한) 건가요?
실제로 저런 오류가 발생시 맛비님께서도 @(posedge clk) 뒤에 딜레이를 붙이곤 하시나요?
혹시 이런 현상을 지칭하는 영단어가 있을까요? (ex) verilog race condition..
용어는 저도 잘 모르겠네요. 확실한건 이 현상은 race condition 은 아닙니다. :)
위와 같은 현상은 RTL simulation 오류인가요? 아니면 의도된(당연한) 건가요?
당연한 겁니다.
실제로 저런 오류가 발생시 맛비님께서도 @(posedge clk) 뒤에 딜레이를 붙이곤 하시나요?
오류가 발생하면 사용합니다. 아니면 real rtl coding 과 비슷한 스타일로도 추가합니다.
답변 감사합니다
1.블로그를 참고하여,
@(posedge CLK)의 구문을 사용하여 clock의 rising edge를 기다린 후 input을 인가하는 것인데,
push가 1'b1, wdata가 data로 올라가 있는 상태에서 CLK이 올라가는 상황으로 인지하는 것은
제가 testbench에서 코딩한 의도대로 simulation이 제대로 나오지 않은 것 아닌가요??
이게 왜 RTL simulation에서 당연한건지 궁금합니다.
2.https://blog.naver.com/PostView.nhn?blogId=chacagea&logNo=221731003805
맛비님 블로그를 참고하였습니다. task가 $write... $이 붙어있는 명령어?라고 이해했는데
하지만 이렇게 task를 작성하여 testbench로 사용하는 경우 문제점이 발생할 수 있다.
의도와는 달리
출처: https://sunshowers.tistory.com/9 [Sunshowers:티스토리]
여기서의 task는 어떤 것을 의미하는 건가요?
3. 맛비님께서 말씀해주신 real rtl coding이란 무엇인가요?
구글 검색으로 나오지 않아서 어떤 스타일을 지칭하는 것인지 궁금합니다.
잘 모르는 건 빠르게 넘어갈께요.
A1. 이 부분은 제 실력 미숙으로 답변이 어려워서 pass 하겠습니다. 교수님 찬스는 어떠실까요..?! :)
A2. Verilog 문법의 task 에 대해 공부해보세요.
A3. 합성가능한 RTL coding 스타일 이다 이해해주시면 되겠습니다.
즐공하세요 :)
강의에서 다룬 내용 외의 질문은... 부담되네요 ㅠ (시간과 노력이... ㅠ) 스스로 해결해보시는 것 + 그 결과를 정리해주시면 감사하겠습니다
0
안녕하세요 :)
BRAM의 데이터를 Read할 때 Testbench에서 address를 1씩 증가시켜서 읽어보면 address와 read data가 동클락에 나오는 걸 방지하기 위해 r_valid로 1 cycle delay 시켜주는 것으로 이해했습니다.
아닙니다. BRAM 의 Read Operation 이 1 cycle delay 가 발생합니다.
r_valid 는 단지 이 1 cycle delay 를 고려해서, BRAM 에서 읽은 Data 가 유요한 시점 을 보여드리기 위해서 사용한 신호입니다. 즉, r_valid 와 무관하게 BRAM 의 Read Operation 은 1 cycle delay 가 발생합니다.
위 코드를 보시면 (true_drpbram.v 발췌) q0 이 곧 BRAM 의 read 결과이죠. addr0 이 입력된 다음 cycle 에 출력이 됨을 아실 수 있을꺼에요. 해당 코드는 모델링 코드이지만 실제 FPGA 에서 BRAM 으로 합성되는 코드입니다.
즉 FPGA 의 BRAM 의 특성은 Read Operation 은 1 cycle delay 가 발생합니다.
즐공하세요 :)
개인코드는 봐드리고 있지않아요.
https://www.inflearn.com/news/312949
즐공하세요 :)