RTL design and basic verilog modules
What is RTL design?
- Describe complex digital system in modular design
- Each module is composed with register, decoder, mulitplexer, opreartor or control logic.
- Each moules are connected with datapath and control signal.
- Module is combination of regiters.
- Register is consist with flip flop.
- Data transfer is implemented by combinational logic.
Basic of Verilog
Logic value system
There are four kinds of logic value system.
- 0 : forcing 0(direct pull to the ground), or resistive 0(large resistance to force value 0), or capacitive 0(capacitance that has a zero charge).
- 1 : forcing 1, resistive 1 and capacitive 1.
- Z : undriven, high-impedance value. no current flow to either supply or ground voltage.
- X: conflict in multiple driven values, unknown value, uninitialized value.
Numbers
Constants in Verilog are integer or real. Integers include logic values(X, Z, 0 and 1).
We can define the number of bit fo interger. The format is
number_of_bits `base_identifier digits. (base_identifiers are b, d, o and h),
Below is table of number representation example.
Representation | In binary | Explanation |
4'd3 | 0011 | Decimal 3, 4-bit number. |
9'hFF | 011111111 | Hexadecimal FF, 9-bit number |
5'b1101 | 01101 | Binay 1101, 5-bit number |
12'hXA | xxxxxxxx1010 | Hexadecimal A, 12-bit number, 8 bits from MSB are x |
12'shA6 | 111110100110 | Hexadecimal A6, 12-bit number, MSB 4 bit is signed. This grammar doen't seems to be used much. |
Array
Representation | Explanation |
reg [7:0] A; | 8-bit vector |
reg B [7:0] | 8 number of 1-bit elemets |
reg [2:0] C [1:0]; | 2 number of 3-bit vector |
reg D [7:0][3:0]; | 8 by 4 two-dimensional memory of 1 bit elements. |
reg [7:0] E [4:0]; | 4 number of 8-bit vector |
reg [3:0] F [7:0][3:0] | 8 by 4 two-dimensional memory of 4-bit vector |
Operators
operation | description | result | note | |
Arithmetic | +, -, *, /, %, ** | basic artihemetic | multi-bit | • bit length of multiply is two operands' bit length addition • bit length of other operators follow longer operand's bit length • plus(+) and minus(-) can be used as unary operator. • If any operand is Z or X result is X. |
Relational | >, >=, <, <= | compare | one-bit | • If any operand is Z or X, result is X • If two operans' bit length are different, short |
Logical equality | ==, != | Equality not including Z or X | one-bit | • If any operand is Z or X, result is X. |
Case | ===, !== | Equality including Z or X | one-bit | |
Logical | &&, ||, ! | Simple logic | one-bit | • If any operand is Z or X, result is X. |
Bit-wise | ~, &, |, ^, ^~, ~^ | Vector logic operation | one-bit | • ^~ and ~^ are both XNOR operator. |
Reduction | &, ~&, |, ~|, ^, ^~, ~^ | Perform operation on all bits | one-bit | • ~& : NAND • ~| : NOR |
Logical shift | <<n, >>n | Zero-fill Shift n places | Multi-bit | |
Arithmetic shift | <<<n, >>>n | Multi-bit | • If operand is unsigned, work same as logical shift. • If oeprand is signed, fill 1 when shift right. |
|
Concatenation | { } | Join bits | Multi-bit | • If aa is 6 bit reg and a is 4 bit reg, after {aa, a} = 10'b11_0111_0111 aa = 6'b110111 a = 4'b0111 |
Replication | {{ }} | Join & replicate | Multi-bit | • {a, 2{b,c], 3{d}} is equal to {a, b, c, b, c, d, d, d} |
Conditinal operator | ? : | If-then-else | Multi bit | • result = a? b : c; if a is 1, result = b. else if a is 0, result = c. |
//operator 'indexed part-select' : ':+'
//[<bit offset> +: <width>]
//example
reg [31:0] reg32;
wire reg_a = reg32[0 +: 8]; // reg[7:0]
wire reg_b = reg32[8*1 +: 8]; // reg[15:8]
wire reg_c = reg32[8*2 +: 8]; // reg[23:16]
wire reg_d = reg32[8*3 +: 8]; // reg[31:24]
Verilog data type
Verilog has net and reg data types.
net
Net represents hardware wire driven by one or more gates or other types of signal sources.
There are various net types in verilog, such as Supply 0, Suppy 1, Wire(tri), Wand(triand), Wor(trior), trireg.
Only wire seems to be used between net, I will just deal with wire in this post. Ports of a module are wire type in default.
Since wire represents hardware wire, we can not store value to wire. We can assign value to wire using continuous assignments. We will discuss about it later part.
reg
Unlike wire, reg can hold variable. reg can be initialized when thery are declared, if user does not initialie, deflaut initialize value of reg is X.
There are other type of reg, such as integer and time. interger is signed 2s-complement number, time is unsigned reg variable at least 64 bits.
Parameters
Parameter do not belong to either the variable or the net group. Parameters are constants and cannot be changed during runtime.
Function
We can use function in verilog, which is similar to function in C. By using function, we can reduce repeated code,
//syntax
//function [automatic] [return_type] name ([port_list]);
// [statements]
//endfunction
//example
function [7:0] sum1 (input [7:0] a, b);
begin
sum = a + b;
end
endfunction
function [7:0] sum2;
input [7:0] a, b;
begin
sum = a + b;
end
endfunction
automatic keyword will make function reentrant and items within the task are dynamically allocated rather than shared between different invocations of the task. automatic keyword is used for recustive function or same functions are called in parallel.
Function rules
- A function cannot contain any time-controlled statements(#, @, wait, posedge, negedge, etc.)
- A function cannot start a task because it may consume simulation time, but can call other function.
- A function should have at least one input
- A function cannot have non-blocking assignments or forece-release or assign-deassign
- A function cannot have any triggers
- A function cannot have an ouptut or inout
Continuous assignment
Continuous assignment is used only in concurrent Verilog bodies.(it means Combinational?)This assignment represent a net driven by gate output or a logic function.
assign a = b & c;
Example of continuous assignment. left hand side must be net type variable. This assignment bacomes active only when input of gate(b & c) changes, and we call be sensitive to b and c;
Procedural assignment
Procedure assignments in Verilog take place in the initial and always procedural constructs.
Procedure flow control
Statements in a procedural body are executed when program flow reaches them.
initial
initial block is executed at the first time of simulation.
initial begin
clk <= 0;
reset <= 1;
end
However, initial block cannot be synthesised, since circuit do not have 'start' point. So it can be only used at testbench.
always
always block is executed every time when port inside () after @.
always @(negedge reset or posedge clk) begin
if(reset) begin
count <= 0;
end
else begin
count <= count + 1;
if (count == 10) count <= 0;
end
end
Above block represent counter that count from 0 from 9 with reset. negedge reset and posedge clk are refered as sensitivity list.
always @(*) begin
result = ~in;
end
// assign result = ~in;
always @(a) begin
if(a) b <= 0;
else b <= 1;
end
// assign b = a? 0 : 1;
We can also make sequential logic like above.
Parameter
Module parameters
local parameter
asdfasdf
- Examples of multiplexer module with various verilog elements.
//Multiplexer using Primitive instantiations
module Multiplexer(input a, b, sel, output out);
wire a_sel, b_sel, s_bar;
not U1 (s_bar, sel);
and U2 (a_sel, a, sel);
and U3 (b_sel, b, s_bar);
or U4 (out, a_sel, b_sel);
end module
// multiplexer not using conditional expression
module Multiplexer(input a, b, sel, output out)
assign out = (a & sel) | (b & ~sel);
end module
//multiplexer with conditional expression
module Multiplexer(input a, b, sel, output out)
assign out = sel ? a: b;
end module
// Multiplexer with always and if else
module Multiplexer(input a, b, sel, output out);
reg out;
always@(a, b, sel) begin
if(sel) out = a;
else out = b;
end
end module