Introduction //简介 |
Hello World Program //Hello World 程序 |
|
Counter Design Block //计数器的块设计 |
|
the above original link:http://www.asic-world.com/verilog/first.html
Introduction |
你如果读过任何一本编程书籍,它是以一个“Hello World"程序,进行开篇的。一旦你写了一个”Hello World"程序,你能自信地说,你能使用该语言做一些 事情了,^_^。。 |
Well I am also going to show how to write a "hello world" program, followed by a "counter" design, in Verilog. 同样,在计数器设计之后,我也将展示给你怎样用Verilog HDL书写一个“Hello world”程序。 |
Hello World Program // Hello World 程序 |
1 //-----------------------------------------------------
2 // This is my first Verilog Program
3 // Design Name : hello_world
4 // File Name : hello_world.v
5 // Function : This program will print 'hello world'
6 // Coder : Deepak
7 //-----------------------------------------------------
8 module hello_world ;
9
10 initial begin
11 $display ("Hello World by Deepak");
12 #10 $finish;
13 end
14
15 endmodule // End of Module hello_world
You could download file hello_world.v here | ||
绿色的字体表示注释;蓝色的表示保留字;Verilog HDL中任何程序都是以保留字 module <module_name>. 在上面的这个例子,第8行有个 module hello_world. (注意:我们可以是哦用哪个编译器的预处理器的语句如include, define等模块声明。 |
Line 10 contains the initial block: this block gets executed only once after the simulation starts, at time=0 (0ns).
第10行有个initial blok:这个块在仿真开始(time = 0)后只执行一次。
This block contains two statements which are enclosed within begin, at line 10, and end, at line 13.
这个块在begin(line 10)、end(line 13)之间具有两个语句.
In Verilog, if you have multiple lines within a block, you need to use begin and end.
在Verilog HDL中,如果在一个块中,你有多个语句,你需要使用 begin 和end。(译者注:相当与C语言中{})。
Module ends with 'endmodule' reserved word, in this case at line 15.
Hello World Program Output // Hello World 程序的输出 |
Hello World by Deepak
Counter Design Block //计数器的设计模块 |
Counter Design Specs //计数器的设计规范 | ||
| ||
Counter Design // 计数器的设计 | ||
1 //----------------------------------------------------- 2 // This is my second Verilog Design 3 // Design Name : first_counter 4 // File Name : first_counter.v 5 // Function : This is a 4 bit up-counter with 6 // Synchronous active high reset and 7 // with active high enable signal 8 //----------------------------------------------------- 9 module first_counter ( 10 clock , // Clock input of the design 11 reset , // active high, synchronous Reset input 12 enable , // Active high enable signal for counter 13 counter_out // 4 bit vector output of the counter 14 ); // End of port list 15 //-------------Input Ports----------------------------- 16 input clock ; 17 input reset ; 18 input enable ; 19 //-------------Output Ports---------------------------- 20 output [3:0] counter_out ; 21 //-------------Input ports Data Type------------------- 22 // By rule all the input ports should be wires 23 wire clock ; 24 wire reset ; 25 wire enable ; 26 //-------------Output Ports Data Type------------------ 27 // Output port can be a storage element (reg) or a wire 28 reg [3:0] counter_out ; 29 30 //------------Code Starts Here------------------------- 31 // Since this counter is a positive edge trigged one, 32 // We trigger the below block with respect to positive 33 // edge of the clock. 34 always @ (posedge clock) 35 begin : COUNTER // Block Name 36 // At every rising edge of clock we check if reset is active 37 // If active, we load the counter output with 4'b0000 38 if (reset == 1'b1) begin 39 counter_out <= #1 4'b0000; 40 end 41 // If enable is active, then we increment the counter 42 else if (enable == 1'b1) begin 43 counter_out <= #1 counter_out + 1; 44 end 45 end // End of Block COUNTER 46 47 endmodule // End of Module counterYou could download file first_counter.v here | ||
Counter Test Bench //计数器 测试程序 | ||
Any digital circuit, no matter how complex, needs to be tested. For the counter logic, we need to provide clock and reset logic. Once the counter is out of reset, we toggle the enable input to the counter, and check the waveform to see if the counter is counting correctly. This is done in Verilog. 任何一个数字电路,无论其多么复杂,都需要测试。对于计数器逻辑,我需要提供一个时钟信号和一个复位逻辑信号。 一旦计数器离开了复位信号,我们触发器是计数器的输入使能信号,并检查波形图来观察计数器的计数是否正确。这些都是用Verilog HDL实现的。 | ||
The counter testbench consists of clock generator, reset control, enable control and monitor/checker logic. Below is the simple code of testbench without the monitor/checker logic. 这个计数器测试程序有一个时钟产生器,复位控制,使能控制,和监视、检查逻辑组成. 下面是一个没有监视、检查逻辑的简单的测试程序。 | ||
1 `include "first_counter.v" 2 module first_counter_tb(); 3 // Declare inputs as regs and outputs as wires 4 reg clock, reset, enable; 5 wire [3:0] counter_out; 6 7 // Initialize all variables 8 initial begin 9 $display ("time\t clk reset enable counter"); 10 $monitor ("%g\t %b %b %b %b", 11 $time, clock, reset, enable, counter_out); 12 clock = 1; // initial value of clock 13 reset = 0; // initial value of reset 14 enable = 0; // initial value of enable 15 #5 reset = 1; // Assert the reset 16 #10 reset = 0; // De-assert the reset 17 #10 enable = 1; // Assert enable 18 #100 enable = 0; // De-assert enable 19 #5 $finish; // Terminate simulation 20 end 21 22 // Clock generator 23 always begin 24 #5 clock = ~clock; // Toggle clock every 5 ticks 25 end 26 27 // Connect DUT to test bench 28 first_counter U_counter ( 29 clock, 30 reset, 31 enable, 32 counter_out 33 ); 34 35 endmoduleYou could download file first_counter_tb.v here | ||
time clk reset enable counter
0 1 0 0 xxxx
5 0 1 0 xxxx
10 1 1 0 xxxx
11 1 1 0 0000
15 0 0 0 0000
20 1 0 0 0000
25 0 0 1 0000
30 1 0 1 0000
31 1 0 1 0001
35 0 0 1 0001
40 1 0 1 0001
41 1 0 1 0010
45 0 0 1 0010
50 1 0 1 0010
51 1 0 1 0011
55 0 0 1 0011
60 1 0 1 0011
61 1 0 1 0100
65 0 0 1 0100
70 1 0 1 0100
71 1 0 1 0101
75 0 0 1 0101
80 1 0 1 0101
81 1 0 1 0110
85 0 0 1 0110
90 1 0 1 0110
91 1 0 1 0111
95 0 0 1 0111
100 1 0 1 0111
101 1 0 1 1000
105 0 0 1 1000
110 1 0 1 1000
111 1 0 1 1001
115 0 0 1 1001
120 1 0 1 1001
121 1 0 1 1010
125 0 0 0 1010
| ||
Counter Waveform // 计数器的波形图 | ||
the above original link: http://www.asic-world.com/verilog/first1.html
对于计数器Verilog程序测试如下:使用Icarus Verilog simulator仿真器测试如下:
1. counter.v
//-----------------------------------------------------
// Design Name : counter
// File Name : counter.v
// Function : This is a 4 bit up-counter with
// Synchronous active high reset and //高电平 reset
// with active high enable signal //高电平 enable
//-----------------------------------------------------
module counter (
clock , // Clock input of the design
reset , // active high, synchronous Reset input
enable , // Active high enable signal for counter
counter_out // 4 bit vector output of the counter
); // End of port list
// port direction
//-------------Input Ports-----------------------------
input clock ;
input reset ;
input enable ;
//-------------Output Ports----------------------------
output [3:0] counter_out ;
//-------------Input ports Data Type-------------------
// By rule all the input ports should be wires
// 规则要求所有输入应该为 wire类 型
wire clock ;
wire reset ;
wire enable ;
//-------------Output Ports Data Type------------------
// Output port can be a storage element (reg) or a wire
// 输出端口可以是存储类型reg(register)或者 连线类型 wire
reg [3:0] counter_out ;
//------------Code Starts Here-------------------------
// Since this counter is a positive edge trigged one,
// We trigger the below block with respect to positive
// edge of the clock.
always @ (posedge clock)
begin : COUNTER // Block Name
// At every rising edge of clock we check if reset is active
// If active, we load the counter output with 4'b0000
if (reset == 1'b1) begin
counter_out <= #1 4'b0000;
end
// If enable is active, then we increment the counter
else if (enable == 1'b1) begin
counter_out <= #1 counter_out + 1;
end
end // End of Block COUNTER
endmodule // End of Module counter
2. counter_test.v
`include "counter.v"
module counter_test;
// Declare inputs as regs and outputs as wires
reg clock, reset, enable;
wire [3:0] counter_out;
// Initialize all variables
initial begin
$display ("time:\t clk\t reset\t enable\t counter");
$monitor ("%3d\t %b\t %b\t %b\t %b",
$time, clock, reset, enable, counter_out);
clock = 1; // initial value of clock
reset = 0; // initial value of reset
enable = 0; // initial value of enable
#5 reset = 1; // Assert the reset
#10 reset = 0; // De-assert the reset
#10 enable = 1; // Assert enable
#200 enable = 0; // De-assert enable
#5 $finish; // Terminate simulation
end
// Clock generator
always begin
#5 clock = ~clock; //Toggle clock every 5 ticks
end
// Connect DUT to test bench
counter U_counter (
clock,
reset,
enable,
counter_out
);
initial begin
$dumpfile("counter.vcd");
$dumpvars;
end
endmodule
3. 编译,测试的过程如下:
4.使用gtkwave输出的波形图如下:
完成测试!