The same designs make using SystemVerilog VHDL and Verilog

Every design contains top module + 3 modules that have the same functionality but written on SystemVerilog, VHDL, and Verilog:

The simulation was written on SystemVerilog. Some simulation projects contain external stimulus files and files with expected simulation results.  

In additionals presents 

All projects are available in https://github.com/SystemVerilog-VHDL-Verilog/VHDL_SV_Verilog

The projects made in Vivado v2019.1.1 (64-bit)

The unexpected results of RTL, Synthesis, Implementation, or Simulations marked by Orange color.

 

Description System Verilog Verilog VHDL

 HDL Example 4.1 COMBINATIONAL LOGIC

HDL Example 4.1 illustrates behavioral descriptions of a module that computes the Boolean function
y = ~a & ~b & ~c | a & ~b & ~c | a & ~b & c
~ - not
& - and
| - or

module sillyfunction_sv
(
input logic a, b, c,
output logic y
);
assign y = ~a & ~b & ~c |
a & ~b & ~c |
a & ~b & c;
endmodule
module sillyfunction_v
(
input a, b, c,
output y
);
assign y = ~a & ~b & ~c |
a & ~b & ~c |
a & ~b & c;
endmodule
 library IEEE; use IEEE.STD_LOGIC_1164.all;

entity sillyfunction_vhd is

port
(
a, b, c: in STD_LOGIC;
y: out STD_LOGIC
);
end;

architecture synth of sillyfunction_vhd is
begin
y <= (not a and not b and not c) or
(a and not b and not c) or
(a and not b and c);
end;

 HDL Example 4.2 INVERTERS

HDL Example 4.2 describes four inverters
connected to 4-bit busses. Bitwise operators

module inv_sv
(
input logic [3:0] a,
output logic [3:0] y
);

assign y = ~a;

endmodule

 
 module inv_v

(
input [3:0] a,
output [3:0] y
);

assign y = ~a;

endmodule

 library IEEE; use IEEE.STD_LOGIC_1164.all;

entity inv_vhd is
port
(
a: in STD_LOGIC_VECTOR(3 downto 0);
y: out STD_LOGIC_VECTOR(3 downto 0)
);
end;

architecture synth of inv_vhd is
begin
y <= not a;
end;

 

 HDL Example 4.3 LOGIC GATES

HDL Example 4.3 demonstrates bitwise operations acting on 4-bit busses for other basic logic functions.


A complete command such as assign y4 = ~(a & b); is called a statement.
assign out = in1 op in2; is called a continuous assignment statement.

 module gates_sv

(
input logic [3:0] a, b,
output logic [3:0] y1, y2, y3, y4, y5
);


/*five different two-input logic
gates acting on 4-bit busses */
assign y1 = a & b; // AND
assign y2 = a | b; // OR
assign y3 = a ^ b; // XOR
assign y4 = ~(a & b); // NAND
assign y5 = ~(a |b); // NOR
endmodule

 module gates_v 

(
input [3:0] a, b,
output [3:0] y1, y2, y3, y4, y5
);


/* Five different two-input logic
gates acting on 4 bit busses */
assign y1 = a & b; // AND
assign y2 = a | b; // OR
assign y3 = a ^ b; // XOR
assign y4 = ~(a & b); // NAND
assign y5 = ~(a | b); // NOR
endmodule

 library IEEE; use IEEE.STD_LOGIC_1164.all;
entity gates_vhd is
port
(
a, b: in STD_LOGIC_VECTOR(3 downto 0);
y1, y2, y3, y4, y5: out STD_LOGIC_VECTOR(3 downto 0)
);
end;


architecture synth of gates_vhd is
begin
-- five different two-input logic gates
-- acting on 4-bit busses
y1 <= a and b;
y2 <= a or b;
y3 <= a xor b;
y4 <= a nand b;
y5 <= a nor b;
end;

HDL Example 4.4 EIGHT-INPUT AND

As one would expect, |, ^, ~&, and ~ | reduction operators are available for OR, XOR, NAND, and NOR as well.
Recall that a multi-input XOR performs parity, returning TRUE if an odd number of inputs are TRUE.

 

module and8_sv
(
input logic [7:0] a,
output logic y, y1
);

assign y = &a;
// &a is much easier to write than
assign y1 = a[7] & a[6] & a[5] & a[4] & a[3] & a[2] & a[1] & a[0];
endmodule

 

module and8_v
(
input [7:0] a,
output y
);
assign y = &a;
// &a is much easier to write than
// assign y a[7] & a[6] & a[5] & a[4] &
// a[3] & a[2] & a[1] & a[0];
endmodule

 

library IEEE; use IEEE.STD_LOGIC_1164.all;
entity and8_vhd is
port
(
a: in STD_LOGIC_VECTOR(7 downto 0);
y: out STD_LOGIC
);
end;


architecture synth of and8_vhd is
begin
y <= a(7) and a(6) and a(5) and a(4) and a(3) and a(2) and a(1) and a(0);
end; 

 HDL Example 4.5 2to1 MULTIPLEXER

HDL Example 4.5 illustrates a 2:1 multiplexer using a conditional assignment.
Conditional assignments select the output from among alternatives based on an input called the condition.

module mux2_sv
(
input logic [3:0] d0, d1,
input logic s,
output logic [3:0] y
);
assign y = s ? d1 : d0;
endmodule
 module mux2_v
(
input [3:0] d0, d1,
input s,
output [3:0] y
);
assign y = s ? d1 : d0;
endmodule
 library IEEE; use IEEE.STD_LOGIC_1164.all;
entity mux2_vhd is
port
(
d0, d1: in STD_LOGIC_VECTOR(3 downto 0);
s: in STD_LOGIC;
y: out STD_LOGIC_VECTOR(3 downto 0)
);
end;
architecture synth of mux2_vhd is
begin
y <= d1 when s = '0' else d0;
end;

 HDL Example 4.6 4to1 MULTIPLEXER

The multiplexer has multiple data (d) and one-hot enable (e) inputs. When one of the enables is asserted, the associated data is passed to the output.

 module mux4_sv
(
input logic [3:0] d0, d1, d2, d3,
input logic [1:0] s,
output logic [3:0] y
);
assign y = s[1] ? (s[0] ? d3 : d2): (s[0] ? d1 : d0);
endmodule

 module mux4_v
(
input [3:0] d0, d1, d2, d3,
input [1:0] s,
output [3:0] y
);
assign y = s[1] ? (s[0] ? d3 : d2) : (s[0] ? d1 : d0);
endmodule

library IEEE; use IEEE.STD_LOGIC_1164.all;
entity mux4_vhd is
port(
d0, d1,d2, d3: in STD_LOGIC_VECTOR(3 downto 0);
s: in STD_LOGIC_VECTOR(1 downto 0);
y: out STD_LOGIC_VECTOR(3 downto 0)--;
--y_1: out STD_LOGIC_VECTOR(3 downto 0)
);
end;


architecture synth1 of mux4_vhd is
begin
y <= d0 when s = "00"
else d1 when s = "01"
else d2 when s = "10"
else d3;

-- next code make uncorrect RTL and Synthesis
--with s select y_1 <=
-- d0 when "00",
-- d1 when "01",
-- d2 when "10",
-- d3 when others;

end;

 HDL Example 4.7 FULL ADDER

P and G are called internal variables, because they are neither inputs nor outputs but are used only internal to the module. They are similar to local variables in programming languages.

module fulladder_sv
(
input logic a, b, cin,
output logic s, cout
);


logic p, g;


assign p = a ^ b;
assign g = a & b;
assign s = p ^ cin;
assign cout = g |(p & cin);
endmodule

module fulladder_v
(
input a, b, cin,
output s, cout
);


wire p, g;


assign p = a ^ b;
assign g = a & b;
assign s = p ^ cin;
assign cout = g | (p & cin);
endmodule

 library IEEE; use IEEE.STD_LOGIC_1164.all;
entity fulladder_vhd is
port
(
a, b, cin: in STD_LOGIC;
s, cout: out STD_LOGIC
);
end;


architecture synth of fulladder_vhd is


signal p, g: STD_LOGIC;


begin
p <= a xor b;
g <= a and b;
s <= p xor cin;
cout <= g or (p and cin);
end;

HDL Example 4.10 TRISTATE BUFFER

 HDLs use x to indicate an invalid logic level. If a bus is simultaneously driven to 0 and 1 by two enabled tristate buffers (or other gates), the result is x, indicating contention. If all the tristate buffers driving a bus are simultaneously OFF, the bus will float, indicated by z.

 module tristate_sv
(
input logic [3:0] a,
input logic en,
output tri [3:0] y
);
assign y = en ? a : 4'bz;
endmodule
 module tristate_v
(
input [3:0] a,
input en,
output [3:0] y
);
assign y = en ? a : 4'bz;
endmodule

 library IEEE; use IEEE.STD_LOGIC_1164.all;
entity tristate_vhd is
port
(
a: in STD_LOGIC_VECTOR(3 downto 0);
en: in STD_LOGIC;
y: out STD_LOGIC_VECTOR(3 downto 0)
);
end;


architecture synth of tristate_vhd is
begin
y <= a when en = '1' else "ZZZZ";
--y <= "ZZZZ" when en = '0' else a;
end;

 HDL Example 4.12 BIT SWIZZLING

Often it is necessary to operate on a subset of a bus or to concatenate (join together) signals to form busses. These operations are collectively known as bit swizzling.

 

//HDL Example 4.12 BIT SWIZZLING

module BIT_SWIZZLING_sv
(
input logic [4:0] C,
input logic [4:0] D,
output logic [8:0] Y
);

assign Y = {C[2:1], {3{D[0]}}, C[0], 3'b101}; //y = c2c1d0d0d0c0101 3'b101 - constant

endmodule

 

//HDL Example 4.12 BIT SWIZZLING

module BIT_SWIZZLING_v
(
input [4:0] C,
input [4:0] D,
output [8:0] Y
);

assign Y = {C[2:1], {3{D[0]}}, C[0], 3'b101}; //y = c2c1d0d0d0c0101 3'b101 - constant

endmodule

library IEEE; use IEEE.STD_LOGIC_1164.all;
entity BIT_SWIZZLING_vhd is
port
(
C: in STD_LOGIC_VECTOR(4 downto 0);
D: in STD_LOGIC_VECTOR(4 downto 0);
Y: out STD_LOGIC_VECTOR(8 downto 0)
);
end;


architecture synth of BIT_SWIZZLING_vhd is
begin
Y <= C(2 downto 1) & D(0) & D(0) & D(0) & C(0) & "101";
end;

 HDL Example 4.14 STRUCTURAL MODEL OF 4to1 MULTIPLEXER

HDL Example 4.14 shows how to assemble a 4:1 multiplexer from three 2:1 multiplexers. Each copy of the 2:1 multiplexer is called an instance. Multiple instances of the same module are distinguished by distinct names, in this case lowmux, highmux, and finalmux.
This is an example of regularity, in which the 2:1 multiplexer is reused many times.

 

module mux4_sv
(
input logic [3:0] d0, d1, d2, d3,
input logic [1:0] s,
output logic [3:0] y
);

logic [3:0] low, high;

mux2_sv lowmux(d0, d1, s[0], low);
mux2_sv highmux(d2, d3, s[0], high);
mux2_sv finalmux(low, high, s[1], y);

endmodule

---------------------------------------------------------

module mux2_sv
(
input [3:0] d0,
input [3:0] d1,
input s,
output [3:0] y
);
assign y = s ? d1 : d0;
endmodule

 

 module mux4_v
(
input [3:0] d0, d1, d2, d3,
input [1:0] s,
output [3:0] y
);

wire [3:0] low, high;

mux2_v lowmux (d0, d1, s[0], low);
mux2_v highmux (d2, d3, s[0], high);
mux2_v finalmux (low, high, s[1], y);

endmodule

---------------------------------------------------------

module mux2_v
(
input [3:0] d0,
input [3:0] d1,
input s,
output [3:0] y
);
assign y = s ? d1 : d0;
endmodule

library IEEE; use IEEE.STD_LOGIC_1164.all;
entity mux4_vhd is
port
(
d0, d1, d2, d3: in STD_LOGIC_VECTOR (3 downto 0);
s: in STD_LOGIC_VECTOR (1 downto 0);
y: out STD_LOGIC_VECTOR (3 downto 0)
);
end;

architecture struct of mux4_vhd is

component mux2_vhd
port
(
d0, d1 : in STD_LOGIC_VECTOR (3 downto 0);
s: in STD_LOGIC;
y: out STD_LOGIC_VECTOR (3 downto 0)
);
end component;

signal low, high: STD_LOGIC_VECTOR (3 downto 0);

begin

lowmux: mux2_vhd
port map (
d0 => d0,
d1 => d1,
s => s(0),
y => low
);
highmux: mux2_vhd port map (d2, d3, s(0), high);
finalmux: mux2_vhd port map (low, high, s(1), y);

end;

 ---------------------------------------------------------

library IEEE; use IEEE.STD_LOGIC_1164.all;
entity mux2_vhd is
port
(
d0: in STD_LOGIC_VECTOR (3 downto 0);
d1: in STD_LOGIC_VECTOR (3 downto 0);
s: in STD_LOGIC;
y: out STD_LOGIC_VECTOR (3 downto 0)
;
end;

architecture synth of mux2_vhd is
begin
y <= d0 when s = '0' else d1;
end;

 HDL Example 4.15 STRUCTURAL MODEL OF 2to1 MULTIPLEXER

The structural modeling to construct a 2:1
multiplexer from a pair of tristate buffers.

 module mux2_sv
(
input logic [3:0] d0, d1,
input logic s,
output tri [3:0] y
);
tristate_sv t0(d0, ~s, y);
tristate_sv t1(d1, s, y);
endmodule

---------------------------------------------------------

 module tristate_sv
(
input logic [3:0] a,
input logic en,
output tri [3:0] y
);
assign y = en ? a : 4'bz;
endmodule

 

module mux2_v
(
input [3:0] d0, d1,
input s,
output [3:0] y
);

tristate_v t0 (d0, ~s, y);
tristate_v t1 (d1, s, y);
endmodule 

---------------------------------------------------------

 module tristate_v
(
input [3:0] a,
input en,
output [3:0] y
);
assign y = en ? a : 4'bz;
endmodule

 

 

library IEEE; use IEEE.STD_LOGIC_1164.all;

entity mux2_vhd is
port
(
d0, d1: in STD_LOGIC_VECTOR(3 downto 0);
s: in STD_LOGIC;
y: out STD_LOGIC_VECTOR(3 downto 0)
);
end;

architecture struct of mux2_vhd is

component tristate_vhd
port
(
a: in STD_LOGIC_VECTOR(3 downto 0);
en: in STD_LOGIC;
y: out STD_LOGIC_VECTOR(3 downto 0)
);
end component;

signal sbar: STD_LOGIC;

begin

sbar <= not s;
t0: tristate_vhd port map(d0, sbar, y);
t1: tristate_vhd port map(d1, s, y);
end; 

---------------------------------------------------------

 library IEEE; use IEEE.STD_LOGIC_1164.all;
entity tristate_vhd is
port
(
a: in STD_LOGIC_VECTOR(3 downto 0);
en: in STD_LOGIC;
y: out STD_LOGIC_VECTOR(3 downto 0)
);
end;
architecture synth of tristate_vhd is
begin
y <= a when en = '1' else "ZZZZ";
--y <= "ZZZZ" when en = '0' else a;
end;

 

 

HDL Example 4.16 ACCESSING PARTS OF BUSSES

shows how modules can access part of a bus. An
8-bit wide 2:1 multiplexer is built using two of the 4-bit 2:1 multiplexers
already defined, operating on the low and high nibbles of the byte.
In general, complex systems are designed
hierarchically. The overall
system is described structurally by instantiating its major components.
Each of these components is described structurally from its building
blocks, and so forth recursively until the pieces are simple enough to
describe behaviorally. It is good style to avoid (or at least to minimize)
mixing structural and behavioral descriptions within a single module.

 

module mux2_8_sv
(
input logic [7:0] d0, d1,
input logic s,
output logic [7:0] y
);

mux2_sv lsbmux(d0[3:0], d1[3:0], s, y[3:0]);
mux2_sv msbmux(d0[7:4], d1[7:4], s, y[7:4]);

endmodule

 

module mux2_8_v
(
input [7:0] d0, d1,
input s,
output [7:0] y
);

mux2_v lsbmux (d0[3:0], d1[3:0], s, y[3:0]);
mux2_v msbmux (d0[7:4], d1[7:4], s, y[7:4]);

endmodule

 

library IEEE; use IEEE.STD_LOGIC_1164.all;
entity mux2_8_vhd is
port
(
d0, d1: in STD_LOGIC_VECTOR(7 downto 0);
s: in STD_LOGIC;
y: out STD_LOGIC_VECTOR(7 downto 0)
);
end;

architecture struct of mux2_8_vhd is

component mux2_vhd
port
(
d0, d1: in STD_LOGIC_VECTOR(3 downto 0);
s: in STD_LOGIC;
y: out STD_LOGIC_VECTOR(3 downto 0)
);
end component;

begin

lsbmux: mux2_vhd port map
(
d0 => d0(3 downto 0),
d1 => d1(3 downto 0),
s => s,
y => y(3 downto 0)
);

msbmux: mux2_vhd port map
(
d0 => d0(7 downto 4),
d1 => d1(7 downto 4),
s => s,
y => y(7 downto 4)
);

end;

 HDL Example 4.17 REGISTER

The flip-flop includes only clk in the sensitive list. It remembers its old value of q until the next rising edge of the clk, even if d changes in the interim.
In contrast, Verilog continuous assignment statements (
assign) and VHDL concurrent assignment statements (<=) are reevaluated any time any of the inputs on the right-hand side changes. Therefore, such code necessarily describes combinational logic.

 

module flop_sv
(
input logic clk,
input logic [3:0] d,
output logic [3:0] q
);

always_ff @(posedge clk)
q <= d;

endmodule

 

module flop_v
(
input clk,
input [3:0] d,
output reg [3:0] q
);

always @ (posedge clk)
q <= d;

endmodule

 

library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity flop_vhd is
port
(
clk: in STD_LOGIC;
d: in STD_LOGIC_VECTOR(3 downto 0);
q: out STD_LOGIC_VECTOR(3 downto 0)
);
end;

architecture synth of flop_vhd is

begin
process(clk) begin
if rising_edge(clk) then
-- if clk'event and clk = '1' then
q <= d;
end if;
end process;

end;

  HDL Example 4.18 RESETTABLE REGISTER

Generally, it is good practice to use resettable registers so that on powerup you can put your system in a known state. The reset may be either asynchronous or synchronous. Recall that asynchronous reset occurs immediately, whereas synchronous reset clears the output only on the next rising edge of the clock.

 module flop_ar_sv
(
input logic clk,
input logic reset,
input logic [3:0] d,
output logic [3:0] q
);
// asynchronous reset


always_ff @(posedge clk, posedge reset)
if (reset)
q <= 4'b0;
else
q <= d;
endmodule

---------------------------------------------------------

module flopr_sr_sv
(
input logic clk,
input logic reset,
input logic [3:0] d,
output logic [3:0] q
);
// synchronous reset
always_ff @(posedge clk)
if (reset)
q <= 4'b0;
else
q <= d;
endmodule

 

module flop_ar_v
(
input clk,
input reset,
input [3:0] d,
output reg [3:0] q
);
// asynchronous reset


always @ (posedge clk, posedge reset)
if (reset)
q <= 4'b0;
else
q <= d;
endmodule

---------------------------------------------------------

module flopr_sr_v
(
input clk,
input reset,
input [3:0] d,
output reg [3:0] q
);
// synchronous reset
always @ (posedge clk)
if (reset)
q <= 4'b0;
else
q <= d;
endmodule

 

 

library IEEE; use IEEE.STD_LOGIC_1164.all;
entity flopr_as_vhd is

port
(
clk, reset: in STD_LOGIC;
d: in STD_LOGIC_VECTOR(3 downto 0);
q: out STD_LOGIC_VECTOR(3 downto 0)
);
end;

architecture asynchronous of flopr_as_vhd is

begin

process(clk, reset) begin
if reset = '1' then
q <= "0000";
elsif rising_edge(clk) then
q <= d;
end if;
end process;
end;

---------------------------------------------------------

library IEEE; use IEEE.STD_LOGIC_1164.all;
entity flopr_sr_vhd is

port
(
clk, reset: in STD_LOGIC;
d: in STD_LOGIC_VECTOR(3 downto 0);
q: out STD_LOGIC_VECTOR(3 downto 0)
);
end;

architecture synchronous of flopr_sr_vhd is

begin

process(clk) begin
if rising_edge(clk) then
if reset = '1' then
q <= "0000";
else
q <= d;
end if;
end if;
end process;
end;

 HDL Example 4.19 RESETTABLE ENABLED REGISTER

Enabled registers respond to the clock only when the enable is asserted.
It is retains its old value if both
reset and en are FALSE.

 

 module flopenr_sv
(
input logic clk,
input logic reset,
input logic en,
input logic [3:0] d,
output logic [3:0] q
);
// asynchronous reset
always_ff @(posedge clk, posedge reset)
if (reset) q <= 4'b0;
else if (en) q <= d;
endmodule

 module flopenr_v
(
input clk,
input reset,
input en,
input [3:0] d,
output reg[3:0] q
);
// asynchronous reset
always @(posedge clk, posedge reset)
if (reset) q <= 4'b0;
else if (en) q <= d;
endmodule
 

library IEEE; use IEEE.STD_LOGIC_1164.all;
entity flopenr_vhd is
port
(
clk, reset, en: in STD_LOGIC;
d: in STD_LOGIC_VECTOR(3 downto 0);
q: out STD_LOGIC_VECTOR(3 downto 0)
);
end;

architecture asynchronous of flopenr_vhd is
-- asynchronous reset
begin
process(clk, reset) begin
if reset = '1' then
q <= "0000";
elsif rising_edge(clk) then
if en ='1' then
q <= d;
end if;
end if;
end process;
end;

 

 HDL Example 4.20 SYNCHRONIZER

A single always/process statement can be used to describe multiple pieces of hardware. For example, consider the synchronizer made of two back-to-back flip-flops. On the rising edge of
clk, d is copied to n1. At the same time, n1 is copied to q.

module sync_sv
(
input logic clk,
input logic d,
output logic q
);
logic n1;
always_ff @(posedge clk)
begin
n1 <= d; // nonblocking
q <= n1; // nonblocking
end
endmodule

module sync_v
(
input clk,
input d,
output reg q
);

reg n1;

always @ (posedge clk)
begin
n1 <= d;
q <= n1;
end
endmodule

library IEEE;
use IEEE.STD_LOGIC_1164.all;
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity sync_vhd is port
(
clk: in
STD_LOGIC;
d: in STD_LOGIC;
q: out STD_LOGIC
);
end;
architecture good of sync_vhd is
signal n1: STD_LOGIC;
begin process(clk)
begin
if rising_edge(clk) then
n1 <= d;
q <= n1;
end if;
end process;
end;

 HDL Example 4.21 Latches Do not do that

A D latch is transparent when the clock is HIGH, allowing data to flow from input to output. The latch becomes opaque when the clock is LOW, retaining its old state. HDL Example 4.22 shows the idiom for a D latch.
Not all synthesis tools support latches well. Unless you know that your tool does support latches and you have a good reason to use them, avoid them, and use edge-triggered flip-flops instead. Furthermore, take care that your HDL does not imply any unintended latches, something that is easy to do if you aren’t attentive. Many synthesis tools warn you when a latch is created; if you didn’t expect one, track down the bug in your HDL

 

 

module latch_sv
(
input logic clk,
input logic [3:0] d,
output logic [3:0] q
);

always_latch // it is similar to always @(clk, d)
if (clk) q <= d;
endmodule

 

module latch_v
(
input clk,
input [3:0] d,
output reg [3:0] q
);

always @ (clk, d)
if (clk) q <= d;
endmodule

library IEEE; use IEEE.STD_LOGIC_1164.all;

entity latch_vhd is
port
(
clk: in STD_LOGIC;
d: in STD_LOGIC_VECTOR(3 downto 0);
q: out STD_LOGIC_VECTOR(3 downto 0)
);
end;

architecture synth of latch_vhd is
begin
process(clk, d)
begin
if clk = '1' then
q <= d;
end if;
end process;
end;

 HDL Example 4.22 INVERTER USING always_process

 However, always/process statements can also be used to describe combinational logic behaviorally if the sensitivity list is written to respond to changes in all of the inputs and the body prescribes the output value for every possible input combination. HDL Example 4.22 uses always/process statements to describe a bank of four inverters.

The example is poor applications of always/process statements for modeling combinational logic because they require more lines than the equivalent approach with assignment statements. Moreover, they pose the risk of inadvertently implying sequential logic if the inputs are left out of the sensitivity list. However, case and if statements are convenient for modeling more complicated combinational logic. case and if statements must appear within always/process statements and are examined in the next sections.

module inv_sv
(
input logic [3:0] a,
output logic[3:0] y
);

always_comb
y = ~a;
endmodule

 

module inv_v
(
input [3:0] a,
output reg [3:0] y
);

always @ (*)
y = ~a;

endmodule

 

library IEEE; use IEEE.STD_LOGIC_1164.all;
entity inv_vhd is
port
(
a: in STD_LOGIC_VECTOR(3 downto 0);
y: out STD_LOGIC_VECTOR(3 downto 0)
);
end;

architecture proc of inv_vhd is

begin
--process(all) begin -- supported in VHDL 1076-2008
process (a) begin
y <= not a;
end process;
end;

 

HDL Example 4.23 FULL ADDER USING always_process

Full adder using intermediate signals
p and g to compute s and cout. It produces the same circuit from
Figure 4.8, but uses
always/process statements in place of assignment
statements.

The example is poor applications of always/process statements for modeling combinational logic because they require more lines than the equivalent approach with assignment statements. Moreover, they pose the risk of inadvertently implying sequential logic if the inputs are left out of the sensitivity list. However, case and if statements are convenient for modeling more complicated combinational logic. case and if statements must appear within always/process statements and are examined in the next sections.

 

module fulladder_sv
(
input logic a, b, cin,
output logic s, cout
);

logic p, g;

always_comb
begin
p = a ^ b; // blocking
g = a & b; // blocking
s = p ^ cin; // blocking
cout = g |(p & cin); // blocking
end
endmodule

 

module fulladder_v
(
input a, b, cin,
output reg s, cout
);
reg p, g;
always @ (*)
begin
p = a ^ b;// blocking
g = a & b;// blocking
s = p ^ cin;// blocking
cout = g | (p & cin);// blocking
end
endmodule
 

library IEEE; use IEEE.STD_LOGIC_1164.all;
entity fulladder_vhd is

port
(
a, b, cin: in STD_LOGIC;
s, cout: out STD_LOGIC
);
end;

architecture synth of fulladder_vhd is
begin
process(all) -- supported in VHDL 1076-2008
--process (a, b, cin)
variable p, g: STD_LOGIC;
begin
p := a xor b; -- blocking
g := a and b; -- blocking
s <= p xor cin;
cout <= g or (p and cin);
end process;
end;

HDL Example 4.24 SEVEN-SEGMENT DISPLAY DECODER

A better application of using the always/process statement for combinational logic is a seven-segment display decoder that takes advantage of the case statement that must appear inside an always/process statement.
The case statement performs different actions depending on the value of its input. A case statement implies combinational logic if all possible input combinations are defined; otherwise, it implies sequential logic, because the output will keep its old value in the undefined cases.

 

module sevenseg_sv
(
input logic [3:0] data,
output logic [6:0] segments
);

always_comb
case(data)
// abc_defg
0: segments = 7'b111_1110;
1: segments = 7'b011_0000;
2: segments = 7'b110_1101;
3: segments = 7'b111_1001;
4: segments = 7'b011_0011;
5: segments = 7'b101_1011;
6: segments = 7'b101_1111;
7: segments = 7'b111_0000;
8: segments = 7'b111_1111;
9: segments = 7'b111_0011;
default: segments = 7'b000_0000;
endcase
endmodule

 

module sevenseg_v
(
input [3:0] data,
output reg [6:0] segments
);

always @ (*)
case (data)
// abc_defg
0: segments = 7'b111_1110;
1: segments = 7'b011_0000;
2: segments = 7'b110_1101;
3: segments = 7'b111_1001;
4: segments = 7'b011_0011;
5: segments = 7'b101_1011;
6: segments = 7'b101_1111;
7: segments = 7'b111_0000;
8: segments = 7'b111_1111;
9: segments = 7'b111_1011;
default: segments = 7'b000_0000;
endcase
endmodule

 

library IEEE; use IEEE.STD_LOGIC_1164.all;
entity sevenseg_vhd is
port
(
data: in STD_LOGIC_VECTOR(3 downto 0);
segments: out STD_LOGIC_VECTOR(6 downto 0)
);
end;

architecture synth of sevenseg_vhd is
begin
process(all) begin --(VHDL 2008)
case data is
-- abcdefg
when X"0" => segments <= "1111110";
when X"1" => segments <= "0110000";
when X"2" => segments <= "1101101";
when X"3" => segments <= "1111001";
when X"4" => segments <= "0110011";
when X"5" => segments <= "1011011";
when X"6" => segments <= "1011111";
when X"7" => segments <= "1110000";
when X"8" => segments <= "1111111";
when X"9" => segments <= "1110011";
when others => segments <= "0000000";
end case;
end process;
end;

HDL Example 4.25 3to8 DECODER

Ordinary decoders are also commonly written with case statements.

module decoder3_8_sv
(
input logic [2:0] a,
output logic [7:0] y
);
always_comb
case(a)
3'b000: y = 8'b00000001;
3'b001: y = 8'b00000010;
3'b010: y = 8'b00000100;
3'b011: y = 8'b00001000;
3'b100: y = 8'b00010000;
3'b101: y = 8'b00100000;
3'b110: y = 8'b01000000;
3'b111: y = 8'b10000000;
default: y = 8'bxxxxxxxx;
endcase
endmodule

module decoder3_8_v
(
input [2:0] a,
output reg [7:0] y
);

always @ (*)
case (a)
3'b000: y = 8'b00000001;
3'b001: y = 8'b00000010;
3'b010: y = 8'b00000100;
3'b011: y = 8'b00001000;
3'b100: y = 8'b00010000;
3'b101: y = 8'b00100000;
3'b110: y = 8'b01000000;
3'b111: y = 8'b10000000;
default: y = 8'bxxxxxxxx;
endcase
endmodule

 module decoder3_8_svmodule decoder3_8_sv
(
input logic [2:0] a,
output logic [7:0] y
);
always_comb case(a)
3'b000: y = 8'b00000001;
3'b001: y = 8'b00000010;
3'b010: y = 8'b00000100;
3'b011: y = 8'b00001000;
3'b100: y = 8'b00010000;
3'b101: y = 8'b00100000;
3'b110: y = 8'b01000000;
3'b111: y = 8'b10000000;
default: y = 8'bxxxxxxxx;
end case
end module

 HDL Example 4.26 PRIORITY CIRCUIT

module priority_sv
(
input logic [3:0] a,
output logic [3:0] y
);
always_comb
if(a[3])y <= 4'b1000;
else if (a[2])y <= 4'b0100;
else if (a[1])y <= 4'b0010;
else if (a[0])y <= 4'b0001;
else y <= 4'b0000;
endmodule

 

 module priority_v
(
input [3:0] a,
output reg [3:0] y
);
always @ (*)
if (a[3]) y = 4'b1000;
else if (a[2]) y = 4'b0100;
else if (a[1]) y = 4'b0010;
else if (a[0]) y = 4'b0001;
else y = 4'b0000;
endmodule
 library IEEE; use IEEE.STD_LOGIC_1164.all;
entity priority_vhd is
port
(
a: in STD_LOGIC_VECTOR(3 downto 0);
y: out STD_LOGIC_VECTOR(3 downto 0)
);
end;
architecture synth of priority_vhd is
begin
--process(all) begin -- VHDL 2008, but --The Condition Operator is not supported yet for simulation (Vivado 2019.1.1)
--process (a) begin
--if a(3) then y <= "1000";
--elsif a(2) then y <= "0100";
--elsif a(1) then y <= "0010";
--elsif a(0) then y <= "0001";
--else y <= "0000";
--end if;
process (a) begin
if a(3) = '1' then y <= "1000";
elsif a(2) = '1' then y <= "0100";
elsif a(1) = '1' then y <= "0010";
elsif a(0) = '1' then y <= "0001";
elsey <= "0000";
end if;
end process;
end;

 

 HDL Example 4.27 PRIORITY CIRCUIT USING casez

Verilog also provides the
casez statement to describe truth tables with don’t cares (indicated with
? in the casez statement).

 module priority_casez_sv
(
input logic [3:0] a,
output logic [3:0] y
);
always_comb
casez(a)
4'b1??? : y <= 4'b1000;
4'b01?? : y <= 4'b0100;
4'b001? : y <= 4'b0010;
4'b0001 : y <= 4'b0001;
default : y <= 4'b0000;
endcase
endmodule
 

module priority_casez_v
(
input [3:0] a,
output reg [3:0] y
);

always @ (*)
casez (a)
4'b1???: y = 4'b1000;
4'b01??: y = 4'b0100;
4'b001?: y = 4'b0010;
4'b0001: y = 4'b0001;
default: y = 4'b0000;
endcase
endmodule

library IEEE; use IEEE.STD_LOGIC_1164.all;
entity priority_casez_vhd is
port
(
a: in STD_LOGIC_VECTOR(3 downto 0);
y: out STD_LOGIC_VECTOR(3 downto 0)
);
end;

architecture dontcare of priority_casez_vhd is

begin
process(all) begin
--casez a is -- Wrong syntacs
--case a is -- wrong design
case? a is -- VHDL 2008 Passed the synthesis, implementation, but not supported in Xilinx simulation tools
--ERROR: [XSIM 43-4187] File "C:/Zynq_Book/VHDL_SV_Verilog/HDL Example 4.27 PRIORITY CIRCUIT USING casez/HDL Example 4_27 PRIORITY CIRCUIT USING casez.srcs/sources_1/imports/HDL Example 4.27 PRIORITY CIRCUIT USING casez/priority_casez.vhd" Line 16 : The "Vhdl 2008 Matching Case Statement" is not supported yet for simulation.
when "1---" =>
y <= "1000";
when "01--" =>
y <= "0100";
when "001-" =>
y <= "0010";
when "0001" =>
y <= "0001";
when others =>
y <= "0000";
--end casez;
--end case;
end case?;
end process;
end;

HDL Example 4.28 FULL ADDER USING NONBLOCKING ASSIGNMENTS not recommended use the nonblocking assigment into combination logic

 

 

// nonblocking assignments (not recommended)
module fulladder_nb_sv
(
input logic a, b, cin,
output logic s, cout
);

logic p, g;

always_comb
begin
p <= a ^ b; // nonblocking
g <= a & b; // nonblocking
s <= p ^ cin;
cout <= g | (p & cin);
end
endmodule

 

// nonblocking assignments (not recommended)
module fulladder_nb_v
(
input a, b, cin,
output reg s, cout
);

//Because p and g appear on the left hand side of an assignment in an always statement, they must be declared to be reg.
reg p, g;

always @ (*)
begin
p <= a ^ b; // nonblocking
g <= a & b; // nonblocking

s <= p ^ cin;
cout <= g | (p & cin);
end
endmodule

 

-- nonblocking assignments (not recommended)
library IEEE; use IEEE.STD_LOGIC_1164.all;
entity fulladder_nb_vhd is
port
(
a, b, cin: in STD_LOGIC;
s, cout: out STD_LOGIC
);
end;

architecture nonblocking of fulladder_nb_vhd is

signal p, g: STD_LOGIC;

begin
-- process (a, b, cin, p, g) begin VHDL
process(all) begin -- VHDL 2008
p <= a xor b; -- nonblocking
g <= a and b; -- nonblocking
s <= p xor cin;
cout <= g or (p and cin);
end process;

end;

 HDL Example 4.29 BAD SYNC W B_ASS Dont make

Because n1 is invisible to the outside world and does not influence
the behavior of
q, the synthesizer optimizes it away entirely

 

// Bad implementation of a synchronizer using blocking // assignments
module syncbad_sv
(
input logic clk,
input logic d,
output logic q
);

logic n1;

always_ff @(posedge clk)

begin
n1 = d; // blocking
q = n1; // blocking
end

endmodule

 

// Bad implementation using blocking assignments
module syncbad_v
(
input clk,
input d,
output reg q
);

reg n1;

always @ (posedge clk)
begin
n1 = d; // blocking
q = n1; // blocking
end
endmodule

 

-- Bad implementation of a synchronizer using blocking –– assignment
library IEEE; use IEEE.STD_LOGIC_1164.all;
entity syncbad_vhd is
port
(
clk: in STD_LOGIC;
d: in STD_LOGIC;
q: out STD_LOGIC
);
end;

architecture bad of syncbad_vhd is
begin

process(clk)
variable n1: STD_LOGIC;
begin
if rising_edge(clk) then
n1 := d; -- blocking
q <= n1;
end if;
end process;

end;

 HDL Example 4.30 DIVIDE-BY-3 FINITE STATE MACHINE

Recall that a finite state machine (FSM) consists of a state register and two
blocks of combinational logic to compute the next state and the output
given the current state and the input

It provides an asynchronous reset to initialize the FSM. The state
register uses the ordinary idiom for flip-flops. The next state and output
logic blocks are combinational.

 

module divideby3FSM_sv
(
input logic clk,
input logic reset,
output logic y
);

typedef enum logic [1:0] {S0, S1, S2} statetype;
statetype [1:0] state, nextstate;

// state register

always_ff @(posedge clk, posedge reset)
if (reset) state <= S0;
else state <= nextstate;

// next state logic
always_comb
case (state)
S0: nextstate <= S1;
S1: nextstate <= S2;
S2: nextstate <= S0;
default: nextstate <= S0;
endcase
// output logic
assign y = (state == S0);

endmodule

 

module divideby3FSM_v
(
input clk,
input reset,
output y
);

reg [1:0] state, nextstate;

parameter S0 = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;

// state register
always @ (posedge clk, posedge reset)
if (reset) state <= S0;
else state <= nextstate;

// next state logic
always @ (*)
case (state)
S0: nextstate = S1;
S1: nextstate = S2;
S2: nextstate = S0;
default: nextstate = S0;
endcase
// output logic
assign y = (state == S0);

endmodule

 

library IEEE; use IEEE.STD_LOGIC_1164.all;
entity divideby3FSM_vhd is
port
(
reset : in STD_LOGIC;
clk : in STD_LOGIC;
y : out STD_LOGIC
);
end;

architecture synth of divideby3FSM_vhd is
type statetype is (S0, S1, S2);
signal state, nextstate: statetype;

begin
-- state register
process(clk, reset)
begin
--if reset then -- VHDL 2008 [XSIM 43-4187] HDL Example 4.30 DIVIDE-BY-3 FINITE STATE MACHINE/divideby3FSM.vhd" Line 19 : The "Vhdl 2008 Condition Operator" is not supported yet for simulation.
if reset = '1' then -- VHDL
state <= S0;
elsif rising_edge(clk) then
state <= nextstate;
end if;
end process;

-- next state logic
nextstate <= S1 when state = S0 else
S2 when state = S1 else
S0;

-- output logic
y <= '1' when state = S0 else '0';

end;

 HDL Example 4.31 PATTERN RECOGNIZER MOORE FSM

The next two examples describe the snail pattern recognizer FSM
 The code shows how to use
case and if statements to handle next state and output logic that depend on the inputs
as well as the current state. In the Moore machine, the output depends
only on the current state

 

//The daughter snail smiles whenever she slides over the pattern 1101.
module patternMoore_sv
(
input logic clk,
input logic reset,
input logic a,
output logic y
);

typedef enum logic [2:0] {S0, S1, S2, S3, S4} statetype;
statetype state, nextstate;

// state register
always_ff @(posedge clk, posedge reset)
if (reset)
state <= S0;
else
state <= nextstate;

// next state logic
always_comb
case (state)
S0: if (a)
nextstate = S1;
else
nextstate = S0;
S1: if (a)
nextstate = S2;
else
nextstate = S0;
S2: if (a)
nextstate = S2;
else
nextstate = S3;
S3: if (a)
nextstate = S4;
else
nextstate = S0;
S4: if (a)
nextstate = S2;
else
nextstate = S0;
default:
nextstate = S0;
endcase

// output logic
assign y = (state == S4);

endmodule

 

//The daughter snail smiles whenever she slides over the pattern 1101.
module patternMoore_v
(
input clk,
input reset,
input a,
output y
);

reg [2:0] state, nextstate;
parameter S0 = 3'b000;
parameter S1 = 3'b001;
parameter S2 = 3'b010;
parameter S3 = 3'b011;
parameter S4 = 3'b100;

// state register
always @ (posedge clk, posedge reset)
if (reset)
state <= S0;
else
state <= nextstate;

// next state logic
always @ (*)
case (state)
S0: if (a)
nextstate = S1;
else
nextstate = S0;
S1: if (a)
nextstate = S2;
else
nextstate = S0;
S2: if (a)
nextstate = S2;
else
nextstate = S3;
S3: if (a)
nextstate = S4;
else
nextstate = S0;
S4: if (a)
nextstate = S2;
else
nextstate = S0;
default:
nextstate = S0;
endcase

// output logic
assign y = (state == S4);

endmodule

 

-- The daughter snail smiles whenever she slides over the pattern 1101 or the pattern 1110.
library IEEE; use IEEE.STD_LOGIC_1164.all;
entity patternMoore_vhd is
port
(
reset : in STD_LOGIC;
clk : in STD_LOGIC;
a : in STD_LOGIC;
y : out STD_LOGIC
);
end;

architecture synth of patternMoore_vhd is
type statetype is (S0, S1, S2, S3, S4);
signal state, nextstate: statetype;

begin
-- state register
process (clk, reset) begin
if reset = '1' then
state <= S0;
elsif clk'event and clk = '1' then
state <= nextstate;
end if;
end process;

-- next state logic
process (state, a) begin
-- process(all) begin
case state is
when S0 =>
if a = '1' then
nextstate <= S1;
else
nextstate <= S0;
end if;
when S1 =>
if a = '1' then
nextstate <= S2;
else
nextstate <= S0;
end if;
when S2 =>
if a = '1' then
nextstate <= S2;
else
nextstate <= S3;
end if;
when S3 =>
if a = '1' then
nextstate <= S4;
else
nextstate <= S0;
end if;
when S4 =>
if a = '1' then
nextstate <= S2;
else
nextstate <= S0;
end if;
when others =>
nextstate <= S0;
end case;
end process;

-- output logic
y <= '1' when state = S4 else '0';
end;

HDL Example 4.32 PATTERN RECOGNIZER MEALY FSM

The next two examples describe the snail pattern recognizer FSM. The code shows how to use case and if statements to handle next state and output logic that depend on the inputs as well as the current state. In the Mealy machine, the output logic depends on both the current state and inputs.

 

//The daughter snail smiles whenever she slides over the pattern 1101.
module patternMealy_sv
(
input logic clk,
input logic reset,
input logic a,
output logic y
);

typedef enum logic [1:0] {S0, S1, S2, S3} statetype;
statetype state, nextstate;

// state register
always_ff @(posedge clk, posedge reset)
if (reset)
state <= S0;
else
state <= nextstate;

// next state logic
always_comb
case (state)
S0:
if (a)
nextstate = S1;
else
nextstate = S0;
S1: if (a)
nextstate = S2;
else
nextstate = S0;
S2:
if (a)
nextstate = S2;
else
nextstate = S3;
S3:
if (a)
nextstate = S1;
else
nextstate = S0;
default:
nextstate = S0;
endcase

// output logic
assign y = (a & state == S3);

endmodule

 

//The daughter snail smiles whenever she slides over the pattern 1101.
module patternMealy_v
(
input clk,
input reset,
input a,
output y
);

reg [1:0] state, nextstate;
parameter S0 = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;
parameter S3 = 2'b11;

// state register
always @ (posedge clk, posedge reset)
if (reset)
state <= S0;
else
state <= nextstate;

// next state logic
always @ (*)
case (state)
S0:
if (a)
nextstate = S1;
else
nextstate = S0;
S1: if (a)
nextstate = S2;
else
nextstate = S0;
S2:
if (a)
nextstate = S2;
else
nextstate = S3;
S3:
if (a)
nextstate = S1;
else
nextstate = S0;
default:
nextstate = S0;
endcase

// output logic
assign y = (a & state == S3);

endmodule

 --The daughter snail smiles whenever she slides over the pattern 1101.
library IEEE;
use IEEE.STD_LOGIC_1164.all;

entity patternMealy_vhd isport
(
reset : in STD_LOGIC;
clk : in STD_LOGIC;
a : in STD_LOGIC;
y : out STD_LOGIC
);
end;

architecture synth of patternMealy_vhd is
type statetype is (S0, S1, S2, S3);
signal state, nextstate: statetype;
begin
-- state register
process (clk, reset) begin
if reset = '1' then
state <= S0;
elsif clk'event and clk = '1' then
state <= nextstate;
end if;
end process;

-- next state logic
process(state, a) begin
case state is
when S0 =>
if a = '1' then
nextstate <= S1;
else
nextstate <= S0;
end if;
when S1 =>
if a = '1' then
nextstate <= S2;
else
nextstate <= S0;
end if;
when S2 =>
if a = '1' then
nextstate <= S2;
else
nextstate <= S3;
end if;
when S3 =>
if a = '1' then
nextstate <= S1;
else
nextstate <= S0;
end if;
when others =>
nextstate <= S0;
end case;
end process;

 HDL Example 4.33a unsigned multiplier

 

// 4.33(a): unsigned multiplier
module multiplier_sv
(
input logic [3:0] a, b,
output logic [7:0] y
);

assign y = a * b;
endmodule

// 5.4(): unsigned multiplier
//module multiplier #(parameter N = 8)
//(input logic [N–1:0] a, b,
//output logic [2*N–1:0] y);
//assign y = a * b;
//endmodule

 

// 4.33(a): unsigned multiplier
module multiplier_v
(
input [3:0] a, b,
output [7:0] y
);
assign y = a * b;
endmodule

//HDL Example 5.4 MULTIPLIER
//module multiplier # (parameter N 8)
//(input [N-1:0] a, b,
//output [2*N-1:0] y);
//assign y a * b;
//endmodule

 -- 4.33(a): unsigned multiplier

library IEEE; use IEEE.STD_LOGIC_1164.all;
--use IEEE.NUMERIC_STD_UNSIGNED.all; -- VHDL2008 (but not always work)
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity multiplier_vhd is
port
(
a: in STD_LOGIC_VECTOR(3 downto 0);
b: in STD_LOGIC_VECTOR(3 downto 0);
y: out STD_LOGIC_VECTOR(7 downto 0)
);
end;

architecture synth of multiplier_vhd is
begin
y <= a * b;
end;

--library IEEE; use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.STD_LOGIC_UNSIGNED.ALL;
--entity multiplier is
--generic (N: integer : 8);
--port (a, b: in STD_LOGIC_VECTOR(N-1 downto 0);
--y: out STD_LOGIC_VECTOR(2*N-1 downto 0));
--end;
--architecture synth of multiplier is
--begin
--y <= a * b;
--end;

 HDL Example 4.33b signed multiplier

 // 4.33(b): signed multiplier
module multiplier_sv
(
input logic signed [3:0] a,
input logic signed [3:0] b,
output logic signed [7:0] y
);
assign y = a * b;
endmodule
 

// 4.33(b): signed multiplier
module multiplier_v
(
input signed [3:0] a,
input signed [3:0] b,
output signed [7:0] y
);

assign y = a * b;
endmodule

 --4.33(b): signed multiplier

library IEEE; use IEEE.STD_LOGIC_1164.all;
use IEEE.NUMERIC_STD.all;
use IEEE.STD_LOGIC_SIGNED.ALL;
--use ieee.std_logic_arith.all ;
--Use numeric_std or std_logic_arith, but never both


entity multiplier_vhd is
port
(
-- a: in SIGNED STD_LOGIC_VECTOR(3 downto 0);
-- b: in SIGNED STD_LOGIC_VECTOR(3 downto 0);
-- y: out SIGNED STD_LOGIC_VECTOR(7 downto 0)
a: in STD_LOGIC_VECTOR(3 downto 0);
b: in STD_LOGIC_VECTOR(3 downto 0);
y: out STD_LOGIC_VECTOR(7 downto 0)
);
end;

architecture synth of multiplier_vhd is

signal a_signed : signed(3 downto 0);
signal b_signed : signed(3 downto 0);
signal y_signed : signed(7 downto 0);

begin
a_signed <= signed(a);
b_signed <= signed(b);
y <= a * b;
y <= std_logic_vector(y_signed);

end;

 

 HDL Example 4.34a PARAMETERIZED N-BIT MULTIPLEXERS

 

module mux4_8_sv
(
input logic [7:0] d0,
input logic [7:0] d1,
input logic [7:0] d2,
input logic [7:0] d3,
input logic [1:0] s,
output logic [7:0] y
);

logic [7:0] low, hi;

mux2_sv lowmux(d0, d1, s[0], low);
mux2_sv himux(d2, d3, s[0], hi);
mux2_sv outmux(low, hi, s[1], y);

endmodule

 

module mux4_8_v
(
input [7:0] d0,
input [7:0] d1,
input [7:0] d2,
input [7:0] d3,
input [1:0] s,
output [7:0] y
);

wire [7:0] low, hi;

mux2_v lowmux (d0, d1, s[0], low);
mux2_v himux (d2, d3, s[0], hi);
mux2_v outmux (low, hi, s[1], y);

endmodule

 library IEEE; use IEEE.STD_LOGIC_1164.all;

entity mux4_8_vhd is
port
(
d0: in STD_LOGIC_VECTOR(7 downto 0);
d1: in STD_LOGIC_VECTOR(7 downto 0);
d2: in STD_LOGIC_VECTOR(7 downto 0);
d3: in STD_LOGIC_VECTOR(7 downto 0);
s: in STD_LOGIC_VECTOR(1 downto 0);
y: out STD_LOGIC_VECTOR(7 downto 0)
);
end;

architecture struct of mux4_8_vhd is

component mux2_vhd
generic(width: integer := 8);
port(
d0: in STD_LOGIC_VECTOR(width-1 downto 0);
d1: in STD_LOGIC_VECTOR(width-1 downto 0);
s: in STD_LOGIC;
y: out STD_LOGIC_VECTOR(width-1 downto 0)
);
end component;

signal low, hi: STD_LOGIC_VECTOR(7 downto 0);

begin
lowmux: mux2_vhd port map(d0, d1, s(0), low);
himux: mux2_vhd port map(d2, d3, s(0), hi);
outmux: mux2_vhd port map(low, hi, s(1), y);
end;

 HDL Example 4.35 PARAMETERIZED Nto2N DECODER

 

module decoder_sv
#(parameter N = 3)
(
input logic [N - 1:0] a,
output logic [2**N - 1:0] y
);

always_comb
begin
y = 0;
y[a] = 1;
end
endmodule

 

module decoder_v
#(parameter N = 3)
(
input [N - 1:0] a,
output reg [2**N - 1:0] y
);

always @ (*)
begin
y = 0;
y[a] = 1;
end
endmodule

 library IEEE; use IEEE.STD_LOGIC_1164.all;

use IEEE. NUMERIC_STD_UNSIGNED.all;

entity decoder_vhd is
generic(N: integer := 3);
port
(
a: in STD_LOGIC_VECTOR(N - 1 downto 0);
y: out STD_LOGIC_VECTOR(2**N - 1 downto 0)
);
end;

architecture synth of decoder_vhd is

begin
--process(all)-- VHDL 2008
process(a)
begin
y <= (OTHERS => '0');
y(TO_INTEGER(a)) <= '1';
end process;
end;

 HDL Example 4.36 PARAMETERIZED N-INPUT AND GATE

 

module andN_sv
#(parameter width = 8)
(
input logic [width - 1:0] a,
output logic y
);

genvar i;
logic [width - 1:0] x;

generate
assign x[0] = a[0];
for(i=1; i<width; i=i+1) begin: forloop
assign x[i] = a[i] & x[i - 1];
end
endgenerate
assign y = x[width - 1];
endmodule

 module andN_v

# (parameter width = 8)
(
input [width-1:0] a,
output y
);

genvar i;
wire [width-1 : 1] x;

generate
for (i=1; i<width; i=i+1) begin:forloop
if (i == 1)
assign x[1] = a[0] & a[1];
else
assign x[i] = a[i] & x[i-1];
end
endgenerate

assign y = x[width-1];
endmodule

 

library IEEE; use IEEE.STD_LOGIC_1164.all;

entity andN_vhd is
generic(width: integer := 8);
port
(
a: in STD_LOGIC_VECTOR(width - 1 downto 0);
y: out STD_LOGIC
);
end;

architecture synth of andN_vhd is

signal x: STD_LOGIC_VECTOR(width - 1 downto 0);

begin

x(0) <= a(0);

gen: for i in 1 to width-1 generate
x(i) <= a(i) and x(i-1);
end generate;

y <= x(width - 1);

end;

--architecture synth of andN is
--signal i: integer;
--signal x: STD_LOGIC_VECTOR (width - 1 downto 1);
--begin
--AllBits: for i in 1 to width-1 generate
--LowBit: if i = 1 generate
--A1: x(1) <= a(0) and a(1);
--end generate;

--OtherBits: if i /= 1 generate
--Ai: x(i) <= a(i) and x(i-1);
--end generate;
--end generate;

--y <= x(width-1);

--end;

 HDL Example 5.1 ADDER  module adder
#(parameter N = 8)
(
input logic [N–1:0] a, b,
input logic cin,
output logic [N–1:0] s,
output logic cout
);
assign {cout, s} = a + b + cin;
endmodule
 

module adder
#(parameter N 8)
(
input [N-1:0] a, b,
input cin,
output [N-1:0] s,
output cout
);

assign {cout, s} = a + b + cin;
endmodule

 

library IEEE; use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity adder is
generic (N: integer : 8);
port
(
a, b: in STD_LOGIC_VECTOR(N-1 downto 0);
cin: in STD_LOGIC;
s: out STD_LOGIC_VECTOR(N-1 downto 0);
cout: out STD_LOGIC
);
end;

architecture synth of adder is

signal result: STD_LOGIC_VECTOR(N downto 0);

begin
result <= (“0” & a) + (“0” & b) + cin;
s <= result (N-1 downto 0);
cout <= result (N);
end;

 HDL Example 5.2 SUBTRACTOR  module subtractor
#(parameter N = 8)
(
input logic [N–1:0] a, b,
output logic [N–1:0] y
);
assign y = a − b;
endmodule
 module subtractor
#(parameter N = 8)
(
input [N–1:0] a, b,
output [N–1:0] y
);
assign y = a − b;
endmodule
 

library IEEE; use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD_UNSIGNED.ALL;

entity subtractor is
generic(N: integer := 8);
port
(
a, b: in STD_LOGIC_VECTOR(N–1 downto 0);
y: out STD_LOGIC_VECTOR(N–1 downto 0)
);
end;

architecture synth of subtractor is
begin
y <= a – b;
end;

 HDL Example 5.3 COMPARATORS  module comparator #(parameter N = 8)
(
input logic [N–1:0] a, b,
output logic eq, neq, lt, lte, gt, gte
);
assign eq = (a == b);
assign neq = (a != b);
assign lt = (a <b);
assign lte = (a <= b);
assign gt = (a >b);
assign gte = (a >= b);
endmodule
 module comparator #(parameter N = 8)
(
input [N–1:0] a, b,
output eq, neq, lt, lte, gt, gte
);
assign eq = (a == b);
assign neq = (a != b);
assign lt = (a <b);
assign lte = (a <= b);
assign gt = (a >b);
assign gte = (a >= b);
endmodule
 library IEEE; use IEEE.STD_LOGIC_1164.ALL;
entity comparators is
generic(N: integer : = 8);
port
(
a, b: in STD_LOGIC_VECTOR(N–1 downto 0);
eq, neq, lt, lte, gt, gte: out STD_LOGIC
);
end;
architecture synth of comparator is
begin
eq <= '1' when (a = b) else '0';
neq <= '1' when (a /= b) else '0';
lt <= '1' when (a < b) else '0';
lte <= '1' when (a <= b) else '0';
gt <= '1' when (a > b) else '0';
gte <= '1' when (a >= b) else '0';
end;
 HDL Example 5.4 MULTIPLIER  module multiplier #(parameter N = 8)
(input logic [N–1:0] a, b,
output logic [2*N–1:0] y);
assign y = a * b;
endmodule
 module multiplier #(parameter N = 8)
(input [N-1:0] a, b,
output [2*N-1:0] y);
assign y = a * b;
endmodule
 

library IEEE; use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD_UNSIGNED.ALL;
entity multiplier is
generic(N: integer := 8);
port
(
a, b: in STD_LOGIC_VECTOR(N–1 downto 0);
y: out STD_LOGIC_VECTOR(2*N–1 downto 0)
);
end;

architecture synth of multiplier is
begin
y <= a * b;
end;

 HDL Example 5.5 COUNTER  module counter #(parameter N = 8)
(
input logic clk,
input logic reset,
output logic [N–1:0] q
);
always_ff @(posedge clk, posedge reset)
if (reset)q <= 0;
else q <= q + 1;
endmodule
 module counter #(parameter N = 8)
(
input clk,
input reset,
output reg [N–1:0] q
);
always @(posedge clk, posedge reset)
if (reset)q <= 0;
else q <= q + 1;
endmodule
 library IEEE; use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD_UNSIGNED.ALL;
entity counter is
generic(N: integer := 8);
port
(
clk, reset: in STD_LOGIC;
q: out STD_LOGIC_VECTOR(N-1 downto 0)
);
end;
architecture synth of counter is
begin
process(clk, reset) begin
if reset then
q <= (OTHERS => '0');
elsif rising_edge(clk) then
q <= q + '1';
end if;
end process;
end;
HDL Example 5.6 SHIFT REGISTER WITH PARALLEL LOAD

module shiftreg
#(parameter N = 8)
(
input logic clk,
input logic reset, load,
input logic sin,
input logic [N–1:0] d,
output logic [N–1:0] q,
output logic sout
);
always_ff @(posedge clk, posedge reset)
if (reset)
q <= 0;
else if (load)
q <= d;
else
q <= {q[N–2:0], sin};

assign sout = q[N–1];

endmodule

module shiftreg
#(parameter N = 8)
(
input clk,
input reset, load,
input sin,
input [N-1:0] d,
output reg [N-1:0] q,
output sout
);

always @ ((posedge clk, posedge reset)
if (reset)
q <= 0;
else if (load)
q <= d;
else
q <= {q[N–2:0], sin};

assign sout = q[N–1];

endmodule

library IEEE; use IEEE.STD_LOGIC_1164.ALL;
entity shiftreg is
generic(N: integer := 8);
port
(
clk, reset: in STD_LOGIC;
load, sin: in STD_LOGIC;
d: in STD_LOGIC_VECTOR(N–1 downto 0);
q: out STD_LOGIC_VECTOR(N–1 downto 0);
sout: out STD_LOGIC
);
end;

architecture synth of shiftreg is

begin

process(clk, reset) begin
if reset = '1' then
q <= (OTHERS => '0');
elsif rising_edge(clk) then
if load then
q <= d;
else
q <= q(N–2 downto 0) & sin;
end if;
end if;
end process;

sout <= q(N–1);

end;

HDL Example 5.7 RAM

module ram #(parameter N = 6, M = 32)
(
input logic clk,
input logic we,
input logic [N–1:0] adr,
input logic [M–1:0] din,
output logic [M–1:0] dout
);

logic [M–1:0] mem [2**N–1:0];

always_ff @(posedge clk)

if (we) mem [adr] <= din;

assign dout = mem[adr];
endmodule

module ram # (parameter N = 6, M = 32)
(
input clk,
input we,
input [N-1:0] adr,
input [M-1:0] din,
output [M-1:0] dout
);

reg [M-1:0] mem [2**N-1:0];

always @ (posedge clk)
if (we)
mem [adr] <= din;

assign dout mem[adr];
endmodule

library IEEE; use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD_UNSIGNED.ALL;
entity ram_array is
generic(N: integer := 6; M: integer := 32);
port
(
clk, we: in STD_LOGIC;
adr: in STD_LOGIC_VECTOR(N–1 downto 0);
din: in STD_LOGIC_VECTOR(M–1 downto 0);
dout: out STD_LOGIC_VECTOR(M–1 downto 0)
);
end;

architecture synth of ram_array is
type mem_array is array ((2**N–1) downto 0) of STD_LOGIC_VECTOR (M–1 downto 0);
signal mem: mem_array;

begin
process(clk) begin
if rising_edge(clk) then
if we = '1' then
mem(TO_INTEGER(adr)) <= din;
end if;
end if;
end process;
dout <= mem(TO_INTEGER(adr));
end;

HDL Example 5.8 ROM module rom
(
input logic [1:0] adr,
output logic [2:0] dout
);
always_comb
case(adr)
2’b00: dout <= 3’b011;
2’b01: dout <= 3’b110;
2’b10: dout <= 3’b100;
2’b11: dout <= 3’b010;
endcase
endmodule
module rom
(
input [1:0] adr,
output [2:0] dout
);
always @ (adr)
case(adr)
2’b00: dout <= 3’b011;
2’b01: dout <= 3’b110;
2’b10: dout <= 3’b100;
2’b11: dout <= 3’b010;
endcase
endmodule
library IEEE; use IEEE.STD_LOGIC_1164.all;
entity rom is
port
(
adr: in STD_LOGIC_VECTOR(1 downto 0);
dout: out STD_LOGIC_VECTOR(2 downto 0)
);
end;
architecture synth of rom is
begin
--process(all) begin--VHDL2008
process (adr) begin
case adr is
when "00" => dout <= "011";
when "01" => dout <= "110";
when "10" => dout <= "100";
when "11" => dout <= "010";
end case;
end process;
end;
HDL Example 5.30 Shifter module leftshift2_32
(
input logic [31:0] a,
output logic [31:0] y
);
assign y = {a[29:0], 2'b0};
endmodule
module leftshift2_32
(
input [31:0] a,
output [31:0] y
);
assign y = {a[29:0], 2'b0};
endmodule
library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity leftshift2_32 is
port
(
a: in STD_LOGIC_VECTOR(31 downto 0);
y: out STD_LOGIC_VECTOR(31 downto 0)
);
end;
architecture synth of leftshift2_32 is
begin
y <= a(29 downto 0) & "00";
end;
HDL Example 5.31 4-bit Left and Right Rotator module ex5_14
(
input logic [3:0] a;
output logic [3:0] right_rotated;
output logic [3:0] left_rotated;
input logic [1:0] shamt;
);
// right rotated
always_comb
case(shamt)
2'b00: right_rotated = a;
2'b01: right_rotated = {a[0], a[3], a[2], a[1]};
2'b10: right_rotated = {a[1], a[0], a[3], a[2]};
2'b11: right_rotated = {a[2], a[1], a[0], a[3]};
default: right_rotated = 4'bxxxx;
endcase
// left rotated
always_comb
case(shamt)
2'b00: left_rotated = a;
2'b01: left_rotated = {a[2], a[1], a[0], a[3]};
2'b10: left_rotated = {a[1], a[0], a[3], a[2]};
2'b11: left_rotated = {a[0], a[3], a[2], a[1]};
default: left_rotated = 4'bxxxx;
endcase
endmodule
module ex5_14
(
input [3:0] a;
output [3:0] right_rotated;
output [3:0] left_rotated;
input [1:0] shamt;
);
// right rotated
always @ (*) // output logic (combinational)
case(shamt)
2'b00: right_rotated = a;
2'b01: right_rotated = {a[0], a[3], a[2], a[1]};
2'b10: right_rotated = {a[1], a[0], a[3], a[2]};
2'b11: right_rotated = {a[2], a[1], a[0], a[3]};
default: right_rotated = 4'bxxxx;
endcase
// left rotated
always @ (*) // output logic (combinational)
case(shamt)
2'b00: left_rotated = a;
2'b01: left_rotated = {a[2], a[1], a[0], a[3]};
2'b10: left_rotated = {a[1], a[0], a[3], a[2]};
2'b11: left_rotated = {a[0], a[3], a[2], a[1]};
default: left_rotated = 4'bxxxx;
endcase
endmodule

library IEEE;
use IEEE.STD_LOGIC_1164.all;
entity ex5_14 is
port
(
a: in STD_LOGIC_VECTOR(3 downto 0);
right_rotated, left_rotated: out STD_LOGIC_VECTOR(3 downto 0);
shamt: in STD_LOGIC_VECTOR(1 downto 0)
);
end;
architecture synth of ex5_14 is

begin
architecture synth of ex5_14 is
begin
-- right-rotated
process(all) begin -- VHDL 2008
case shamt is
when "00" => right_rotated <= a;
when "01" => right_rotated <= (a(0), a(3), a(2), a(1));
when "10" => right_rotated <= (a(1), a(0), a(3), a(2));
when "11" => right_rotated <= (a(2), a(1), a(0), a(3));
when others => right_rotated <= "XXXX";
end case;
end process;

-- left-rotated
process(all) begin
case shamt is
when "00" => left_rotated <= a;
when "01" => left_rotated <= (a(2), a(1), a(0), a(3));
when "10" => left_rotated <= (a(1), a(0), a(3), a(2));
when "11" => left_rotated <= (a(0), a(3), a(2), a(1));
when others => left_rotated <= "XXXX";
end case;
end process;
end;