Add some examples as documentation.

This commit is contained in:
steve 1999-12-05 21:08:56 +00:00
parent 09de918198
commit b688cdbc40
3 changed files with 287 additions and 0 deletions

47
examples/hello.vl Normal file
View File

@ -0,0 +1,47 @@
/*
* Copyright (c) 1998 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/*
* Here we have the canonical "Hello, World" program written in Verilog.
* We simply print to the program output a simple message. This example
* demonstrates the process of compiling and executing a program with
* Icarus Verilog.
*
* Compile this program with the command:
*
* verilog hello.vl
*
* After churning for a little while, the program will create the output
* file "hello" which is compiled, linked and ready to run. Run this
* program like so:
*
* ./hello
*
* and the program will print the message to its output. Easy!
*/
module main();
initial
begin
$display("Hello, World");
$finish ;
end
endmodule

113
examples/show_vcd.vl Normal file
View File

@ -0,0 +1,113 @@
/*
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
/*
* This example program simulates a 16x1 ram, and is used as an
* example for using VCD output and waveform viewers.
*
* Like any other Verilog simulation, compile this program with the
* command:
*
* verilog show_vcd.vl
*
* This will generate the show_vcd command in the current directory.
* When you run the command, you will see the output from all the
* calls to $display, but also there will be a dump file ``show_vcd.vcd''.
* The name of this file is set by the statement:
*
* $dumpfile("show_vcd.vcd");
*
* in the main module. The output file uses the standard VCD file format
* so can be viewed using off-the-shelf waveform viewers. The following
* describes how to use GTKWave to view the file.
*
* To view the output generated by running show_vcd, start the GTKWave
* viewer with the command:
*
* wave show_vcd.vcd
*
* The GTKWave program will display its main window, and show is a small
* status bux (upper left corner) that it succeeded in loading the dump
* file. However, there are no waveforms displayed. Select signals to
* add to the waveform display using the menu selection:
*
* "Search --> Signal Search Tree"
*
* This will bring up a dialog box that shows in directory tree format
* the signals of the program. Select the signals you wish to view, and
* click one of the buttons on the bottom of the dialog box to display
* the selectd signals in the waveform window. Click "Exit" on the box
* to get rid of it.
*
* The magic that makes all this work is contained in the $dumpfile and
* $dumpvars system tasks. The $dumpfile task tells the simulation where
* to write the VCD output. This task must be called once before the
* $dumpvars task is called.
*
* The $dumpvars task tells the simulation what variables to write to
* the VCD output. The first parameter is how far to descend while
* scanning a scope, and the remaining paramters are signals or scope
* names to include in the dump. If a scope name is given, all the
* signals within the scope are dumped. If a wire or register name is
* given, that signal is included.
*/
module ram16x1 (q, d, a, we, wclk);
output q;
input d;
input [3:0] a;
input we;
input wclk;
reg mem[15:0];
assign q = mem[a];
always @(posedge wclk) if (we) mem[a] = d;
endmodule /* ram16x1 */
module main;
wire q;
reg d;
reg [3:0] a;
reg we, wclk;
ram16x1 r1 (q, d, a, we, wclk);
initial begin
$dumpfile("show_vcd.vcd");
$dumpvars(1, main.r1);
wclk = 0;
we = 1;
for (a = 0 ; a < 4'hf ; a = a + 1) begin
d = a[0];
#1 wclk = 1;
#1 wclk = 0;
$display("r1[%x] == %b", a, q);
end
for (a = 0 ; a < 4'hf ; a = a + 1)
#1 if (q !== a[0]) begin
$display("FAILED -- mem[%h] !== %b", a, a[0]);
$finish;
end
$display("PASSED");
end
endmodule /* main */

127
examples/sqrt.vl Normal file
View File

@ -0,0 +1,127 @@
/*
* Copyright (c) 1999 Stephen Williams (steve@icarus.com)
*
* This source code is free software; you can redistribute it
* and/or modify it in source code form under the terms of the GNU
* General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
* $Id: sqrt.vl,v 1.1 1999/12/05 21:08:56 steve Exp $"
*/
/*
* This module approximates the square root of an unsigned 32bit
* number. The algorithm works by doing a bit-wise binary search.
* Starting from the most significant bit, the accumulated value
* tries to put a 1 in the bit position. If that makes the square
* to big for the input, the bit is left zero, otherwise it is set
* in the result. This continues for each bit, decreasing in
* significance, until all the bits are calculated or all the
* remaining bits are zero.
*
* Since the result is an integer, this function really calculates
* value of the expression:
*
* x = floor(sqrt(y))
*
* where sqrt(y) is the exact square root of y and floor(N) is the
* largest integer <= N.
*
* For 32bit numbers, this will never run more then 16 iterations,
* which amounts to 16 clocks.
*/
module sqrt32(clk, rdy, reset, x, .y(acc));
input clk;
output rdy;
input reset;
input [31:0] x;
output [15:0] acc;
// acc holds the accumulated result, and acc2 is the accumulated
// square of the accumulated result.
reg [15:0] acc;
reg [31:0] acc2;
// Keep track of which bit I'm working on.
reg [4:0] bitl;
wire [15:0] bit = 1 << bitl;
wire [31:0] bit2 = 1 << (bitl << 1);
// The output is ready when the bitl counter underflows.
wire rdy = bitl[4];
// guess holds the potential next values for acc, and guess2 holds
// the square of that guess. The guess2 calculation is a little bit
// subtle. The idea is that:
//
// guess2 = (acc + bit) * (acc + bit)
// = (acc * acc) + 2*acc*bit + bit*bit
// = acc2 + 2*acc*bit + bit2
// = acc2 + 2 * (acc<<bitl) + bit
//
// This works out using shifts because bit and bit2 are known to
// have only a single bit in them.
wire [15:0] guess = acc | bit;
wire [31:0] guess2 = acc2 + bit2 + ((acc << bitl) << 1);
task clear;
begin
acc = 0;
acc2 = 0;
bitl = 15;
end
endtask
initial clear;
always @(reset or posedge clk)
if (reset)
clear;
else begin
if (guess2 <= x) begin
acc <= guess;
acc2 <= guess2;
end
bitl <= bitl - 1;
end
endmodule
module main;
reg clk, reset;
reg [31:0] value;
wire [15:0] result;
wire rdy;
sqrt32 root(.clk(clk), .rdy(rdy), .reset(reset), .x(value), .y(result));
always #5 clk = ~clk;
always @(posedge rdy) begin
$display("sqrt(%d) --> %d", value, result);
$finish;
end
initial begin
clk = 0;
reset = 1;
$monitor($time,,"%m = %b", root.acc, root.acc);
#100 value = 63;
reset = 0;
end
endmodule /* main */