인프런 커뮤니티 질문&답변
simple_bram_ctrl.v에 true_dpbram.v를 instantiation 을 어떻게 해야 할까요?
작성
·
744
1
안녕하세요
simple_bram_ctrl.v 의 148 째줄 밑에 아래와 같이
true_dpbram.v를 instantiation을 해서 시뮬레이션을 돌리면 test bench에서 콘트롤러 모듈만 instantiation해 주면 되겠다 싶어서 나름 응용해 보고자 아래 처럼 instantiation 해줘서 vivado에서 implantation을 해 줬는데요 자꾸 error가 나오네요.
제생각에는 콘트롤러의 q0 포트가 input 인데 true_dpbram 모듈의 q0는 out put이라서 그런거 같은데 포트를 어떻게 매치 시켜줄야 instantiation이 될까요?
아래는 에러 메세지 입니다.
퀴즈
하드웨어 설계에서 FSM(Finite State Machine)의 주요 목적은 무엇일까요?
데이터 저장 용량 최대화
제어 로직을 체계적으로 설계
클럭 주파수 자동 조정
전력 소모량 실시간 측정
답변 2
1
제공해 주신 simple_bram_ctrl.v 마지막에 true_dpbram.v 를 instantiation 한 코드만 아래와 같이추가한 단순한 코드입니다.
전체 코드도 첨부 하였습니다.
true_dpbram
#( .DWIDTH (DWIDTH),
.AWIDTH (AWIDTH),
.MEM_SIZE (MEM_SIZE))
u_TDPBRAM(
.clk (clk),
.addr0 (addr0),
.ce0 (ce0),
.we0 (we0),
.q0 (q0),
.d0 (d0),
// no use port B.
.addr1 (0),
.ce1 (0),
.we1 (0),
.q1 (),
.d1 (0)
);
//////////////////////////////////////////////////////////////////////////////////
// Company: Personal
// Engineer: Matbi / Austin
//
// Create Date: 2021.01.31
// Design Name:
// Module Name: simple_bram_ctrl
// 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 simple_bram_ctrl
// Param
#(
parameter DWIDTH = 16,
parameter AWIDTH = 7,
parameter MEM_SIZE = 128
)
(
input clk,
input reset_n,
input i_run,
input [AWIDTH-1:0] i_num_cnt,
output o_idle,
output o_write,
output o_read,
output o_done,
// Memory I/F
output[AWIDTH-1:0] addr0,
output ce0,
output we0,
input [DWIDTH-1:0] q0,
output[DWIDTH-1:0] d0,
// output read value from BRAM
output o_valid,
output[DWIDTH-1:0] o_mem_data
);
/////// Local Param. to define state ////////
localparam S_IDLE = 2'b00;
localparam S_WRITE = 2'b01;
localparam S_READ = 2'b10;
localparam S_DONE = 2'b11;
/////// Type ////////
reg [1:0] c_state; // Current state (F/F)
reg [1:0] n_state; // Next state (Variable in Combinational Logic)
wire is_write_done;
wire is_read_done;
/////// Main ////////
// Step 1. always block to update state
always @(posedge clk or negedge reset_n) begin
if(!reset_n) begin
c_state <= S_IDLE;
end else begin
c_state <= n_state;
end
end
// Step 2. always block to compute n_state
//always @(c_state or i_run or is_done)
always @(*)
begin
n_state = c_state; // To prevent Latch.
case(c_state)
S_IDLE : if(i_run)
n_state = S_WRITE;
S_WRITE : if(is_write_done)
n_state = S_READ;
S_READ : if(is_read_done)
n_state = S_DONE;
S_DONE : n_state = S_IDLE;
endcase
end
// Step 3. always block to compute output
// Added to communicate with control signals.
assign o_idle = (c_state == S_IDLE);
assign o_write = (c_state == S_WRITE);
assign o_read = (c_state == S_READ);
assign o_done = (c_state == S_DONE);
// Step 4. Registering (Capture) number of Count
reg [AWIDTH-1:0] num_cnt;
always @(posedge clk or negedge reset_n) begin
if(!reset_n) begin
num_cnt <= 0;
end else if (i_run) begin
num_cnt <= i_num_cnt;
end else if (o_done) begin
num_cnt <= 0;
end
end
// Step 5. increased addr_cnt
reg [AWIDTH-1:0] addr_cnt;
assign is_write_done = o_write && (addr_cnt == num_cnt-1);
assign is_read_done = o_read && (addr_cnt == num_cnt-1);
always @(posedge clk or negedge reset_n) begin
if(!reset_n) begin
addr_cnt <= 0;
end else if (is_write_done || is_read_done) begin
addr_cnt <= 0;
end else if (o_write || o_read) begin
addr_cnt <= addr_cnt + 1;
end
end
// Assign Memory I/F
assign addr0 = addr_cnt;
assign ce0 = o_write || o_read;
assign we0 = o_write;
assign d0 = addr_cnt; // same value;
// output data from memory
reg r_valid;
reg [DWIDTH-1:0] r_mem_data;
// 1 cycle latency to sync mem output
always @(posedge clk or negedge reset_n) begin
if(!reset_n) begin
r_valid <= 0;
end else begin
r_valid <= o_read; // read data
end
end
assign o_valid = r_valid;
assign o_mem_data = q0; // direct assign, bus Matbi recommends you to add a register for timing.
true_dpbram
#( .DWIDTH (DWIDTH),
.AWIDTH (AWIDTH),
.MEM_SIZE (MEM_SIZE))
u_TDPBRAM(
.clk (clk),
.addr0 (addr0),
.ce0 (ce0),
.we0 (we0),
.q0 (q0),
.d0 (d0),
// no use port B.
.addr1 (0),
.ce1 (0),
.we1 (0),
.q1 (),
.d1 (0)
);
endmodule
true_dpbram 모듈의 q0를 o_mem_data에 연결해 주니 instantiation 이 되네요. 너무 쉽게 해결 되네요. input qO를 어떻게든 이용해야 한다고 생각이 고정 되어있던 것 같습니다. 조언 해 주신 대로ㅐoutput q0를 버리고 바로 o_mem_data에 연결해 주면 되는 되는데요^^
아래는 instatntiation을 위한 변형해본 코드 입니다.
저는 개인적으로는 두개의 모듈을 instantiation 해서 하나의 모듈로 만들어서 비바도에서 implantation도 해 볼수 있어서 더 좋았던 것 같습니다. 같지만 다른 두 디자인인데 각자 어떤 잇점이 있을 까요? 강의에서 보여주신 것 처럼 두개 의 dotv 파일을 tb로 묵어서 시뮬레이션을 보여주신 숨은 의도? 가 있을 까요?^^
assign o_valid = r_valid;
//assign o_mem_data = q0; // direct assign, bus Matbi recommends you to add a register for timing.
true_dpbram
#( .DWIDTH (DWIDTH),
.AWIDTH (AWIDTH),
.MEM_SIZE (MEM_SIZE))
u_TDPBRAM(
.clk (clk),
.addr0 (addr0),
.ce0 (ce0),
.we0 (we0),
.q0 (o_mem_data),
.d0 (d0),
// no use port B.
.addr1 (0),
.ce1 (0),
.we1 (0),
.q1 (),
.d1 (0)
);
안녕하세요 :)
먼저, 코드 수정 부분은.
지금 처럼 모듈 내부에 Memory 가 들어가는 상황에서 "memory port 를 in / output 으로 사용할 필요가 없다" 였구요. 그렇게 해결 하셨으리라 믿습니다.
강의에서 보여주신 것 처럼 두개 의 dotv 파일을 tb로 묵어서 시뮬레이션을 보여주신 숨은 의도? 가 있을 까요?^^
"Memory Controller 를 설계해보자" 여서, Memory 를 바깥으로 빼서 설계해 봤어요. 만약에 질문자님이 설계자이다. 그런데 넣는게 좋아보인다. 그러면 넣으시면 됩니다. (설계자 마음대로!)
하지만, 현업가시면, Memory 는 모아서 관리합니다.
즉, 제 강의 코드처럼 Memory 는 바깥에 있다 라는 가정하에 설계하실 가능성이 높아요.
그런데, 지금은 공부하는 입장이니까, 이런 부분에 연연? 하시지 마시고, 마음껏 많이 설계해 보세요.
그럼 즐공하세요~~ :)
0
안녕하세요 :)
Multiple Driver Nets 는 input, output port 를 중복 사용을 해서 그런 것 같구요.
현재 캡쳐해주신 내용만으로는 잘 모르겠습니다.
q0 에 관한 내용 전부를 확인해보고 싶어요.
추가적으로 코드를 남겨주시겠어요?
많은 정보를 주시면 해결에 도움이 될 것 같아요 :)
(코드를 전부 올려주시는 것도 방법)





아하.....
바로 파악했구요.
그래서 이렇게 적어주셨군요.
제생각에는 콘트롤러의 q0 포트가 input 인데 true_dpbram 모듈의 q0는 out put이라서 그런거 같은데 포트를 어떻게 매치 시켜줄야 instantiation이 될까요?
제가 답을 알려드리기 전에 이 그림에 대해서 생각해 보시겠어요? (먼저 20장 그림을 가져왔습니다.)
제가 몰라서... 일 수도 있는데!!! (실력이 부족한 맛비... ㅠ.ㅠ)
질문자님께서 스스로 찾으시기를 바라는 마음에서 적습니다.
후배님께 설계 Tip 을 드리자면, Verilog HDL 을 코딩하기 전에 Architecture 를 먼저 고민하시기를 바랍니다.
지금 이 상황을 다음처럼 바꾸고 싶어하시는 것 같아요.
Hint 를 드리자면,
.
.
.
.
.
.
DUT 에서 Port A 에 대한 in /out port 가 필요할까요?
Wire 로 변경하여서, port 를 연결한다면? 어떻게 될까요?
고민해보시고, 코드를 수정해서 다시 남겨주세요.
아 참고로! 못맞추셔도 됩니다. (괴롭히는거 아니에요. 오해하지 말아주세요.)
시도한 내용을 정리해서 남겨주세요.
우리는 공부하는 입장이니까요!!
즐공입니다. :)