월요일, 9월 22, 2014

[2014-2/VLSI-DA] 3주차 " Basics of Verilog HDL"

[2014년2학기/VLSI-DA] 3주차 " Basics of Verilog HDL"

[VLSI-DA/W03] Basics of Verilog HDL

- How to simulate concurrent execution in the HDL which is a kind of computer language ?
- Blocked or Non-Blocked assignment in Verilog HDL.
- Design example "Synchronous MOD-10 Counter"
All student must submit "HOMEWORK 01" as printed form before today's class. We'll talk with your submitted homework.
- Basics of Testbench
- HOW to use ICARUS Verilog Simulator
Find attached files for your self-study.

Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill!

수업에 사용할 Verilog 시뮬레이터는 ICARUS iVerilog 입니다. 상용 시뮬레이터는 고가입니다. 학습용으로 손색이 없는 무료 시뮬레이터 입니다. 이런 소프트웨어를 개발하는 이들에게 감사 합니다.

리눅스용 이지만 윈도우즈 용도 있습니다.

iVerilog User Guide WiKi

수강생 중에 HDL의 경험이 없는 학생이 90%가 넘습니다. 그렇다고 대학원 수업에서 문법과 구문을 하나하나 가르칠 수는 없습니다. 일단 HDL도 컴퓨터 언어의 하나이며, 그 근원은 자연어(영어)와 기초 대수라는 점을 인식 시킵니다. 각 언어마다 형식의 차이가 있을 뿐이라는 점도 쉽게 전달 됩니다.

예를 들어 "if" 라는 영어 단어를 모를리 없죠. 이 단어가 컴퓨터 언어에서 쓰이는 용도도 금방 이해합니다. C언어에서나 Verilog 언어에서나 용도는 다르지 않습니다. 자신의 생각(아이디어 혹은 알고리듬)을 가지고 있어야 합니다. 언어는 그저 도구일 뿐이라는 점입니다. 도구와 기법은 알려줄 터이니 생각을 가지라고 말해 줍니다.

수업이 Verilog HDL을 접해보지 않았다는 학생들에게 첫 과제로 너무 어려운 과제일지 모르지만 그동안 배워온 지식을 동원해 보기로 합니다.

먼저 16-비트 카운터를 DUT(Design Under Test) 삼아 설계해 봅니다.

//-------------------------------------------------
// File: count16.v
// Purpose: Verilog Simulation Example
//-------------------------------------------------
`timescale 1 ns / 100 ps

module count16 (count, count_tri, clk, rst_l, load_l, enable_l, cnt_in, oe_l);
output [3:0] count;
output [3:0] count_tri;
input clk;
input rst_l;
input load_l;
input enable_l;
input [3:0] cnt_in;
input oe_l;

reg [3:0] count;

// tri-state buffers
assign count_tri = (!oe_l)? count : 4'bzzzz;
// synchronous 4 bit counter
always @ (posedge clk or negedge rst_l)
begin
if (!rst_l) begin
count <= #1 4'b0000;
end
else if (!load_l) begin
count <= #1 cnt_in;
end
else if (!enable_l) begin
count <= #1 count + 1;
end
end

endmodule //of count16

HDL 로 설계는 아주 쉽지요. 이런 카운터를 종래의 논리회로 설계법과 비교하면 이렇게 쉬울순 없습니다. 이미 알고있는 언어적 상식과 하드웨어 특성 그리고 기초적인 Verilog 요소를 동원하면 금방 이해할 수 있습니다.

module ~ endmodule

HDL에는 병렬구문과 순차구문이 있다는 것을 이해합니다.

assign .....;

always @() begin ~ end

병렬 구문을 소프트웨어로 모의(simulate)하는 방법을 설명합니다. 보통 소프트웨어 언어의 문장 실행은 evaluation 즉시 저장 실행 되지만 HDL의 병렬 구문은 evaluation 후 event 수집 검사(aggregate event)후 최종 적용(update) 된다는 것을 설명해 줍니다.

정작 적재 가능한 16-비트 카운터(Loadable Counter)의 행위를 묘사하는 것은 그리 어렵지 않습니다. 누구나 다아는 if 구문이죠.

if () begin ~ end

이어서 테스트 벤치를 만들어 보죠.

//-------------------------------------------------
// File: cnt16_tb.v
// Purpose: Verilog Simulation Example
// Test Bench
//--------------------------------------------------
`timescale 1 ns / 100 ps
module cnt16_tb ();
//----------------------------------------------
// inputs to the DUT are reg type
reg clk_50;
reg rst_l, load_l, enable_l;
reg [3:0] count_in;
reg oe_l;

//----------------------------------------------
// outputs from the DUT are wire type
wire [3:0] cnt_out;
wire [3:0] count_tri;

//----------------------------------------------
// instantiate the Device Under Test (DUT)
// using named instantiation
count16 U1
(
.count(cnt_out),
.count_tri(count_tri),
.clk(clk_50),
.rst_l(rst_l),
.load_l(load_l),
.cnt_in(count_in),
.enable_l(enable_l),
.oe_l(oe_l)
);

//----------------------------------------------
// create a 50Mhz clock
always
#10 clk_50 = ~clk_50; // every ten nanoseconds invert

//----------------------------------------------
// initial blocks are sequential and start at time 0
initial
begin
$dumpfile("counter16.vcd");
$dumpvars(0, cnt16_tb);
$display($time, " << Starting the Simulation >>");
clk_50 = 1'b0; // at time 0
rst_l = 0; // reset is active
enable_l = 1'b1; // disabled
load_l = 1'b1; // disabled
count_in = 4'h0; // initialize counter val.
oe_l = 4'b0; // enabled

#20 rst_l = 1'b1; // at time 20 release reset
$display($time, " << Coming out of reset >>");
@(negedge clk_50); // wait till the negedge of
// clk_50 then continue
load_count(4'hA); // call the load_count task
@(negedge clk_50);
$display($time, " << Turning ON the count enable >>");
enable_l = 1'b0; // turn ON enable
// let the simulation run,
// the counter should roll
wait (cnt_out == 4'b0001); // wait until the count
// equals 1 then continue
$display($time, " << count = %d - Turning OFF the count enable >>", cnt_out);
enable_l = 1'b1;
#40; // let the simulation run for 40ns
// the counter shouldn't count
$display($time, " << Turning OFF the OE >>");
oe_l = 1'b1;
// disable OE, the outputs of
// count_tri should go high Z.
#20;
$display($time, " << Simulation Complete >>");
$stop; // stop the simulation
end
//---------------------------------------------------------
// This initial block runs concurrently with the other
// blocks in the design and starts at time 0
initial
begin
// $monitor will print whenever a signal changes
// in the design
$monitor($time,
" clk_50=%b,rst_l=%b,enable_l=%b,load_l=%b,count_in=%h,cnt_out=%h,oe_l=%b, count_tri=%h",
clk_50, rst_l, enable_l, load_l, count_in, cnt_out, oe_l, count_tri);
end
//---------------------------------------------------------
// The load_count task loads the counter with the value passed
task load_count;
input [3:0] load_value;
begin
@(negedge clk_50);
$display($time, " << Loading the counter with %h >>", load_value);
load_l = 1'b0;
count_in = load_value;
@(negedge clk_50);
load_l = 1'b1;
end
endtask //of load_count

endmodule //of cnt16_tb

Verilog 언어 입문용으로는 조금 과한 듯도 합니다만, 이제껏 배워온 지식과 직감을 총동원하면 전혀 모를것도 아닙니다. 대략적인 설명을 해줬지만 다음주에 한번더 설명해야 겠습니다.

댓글 없음:

댓글 쓰기