Project 4
Project 4
Introduction
This report presents the RTL design and functional verification of a 3-to-8 Decoder using Verilog.
The design consists of three input lines and eight output lines, where each output is activated based
on the binary value of the input. The implementation was verified using EDAPlayground with the
Cadence Xcelium simulator.
A B C Y7 Y6 Y5 Y4 Y3 Y2 Y1 Y0
0 0 0 1 1 1 1 1 1 1 0
0 0 1 1 1 1 1 1 1 0 1
0 1 0 1 1 1 1 1 0 1 1
0 1 1 1 1 1 1 0 1 1 1
1 0 0 1 1 1 0 1 1 1 1
1 0 1 1 1 0 1 1 1 1 1
1 1 0 1 0 1 1 1 1 1 1
1 1 1 0 1 1 1 1 1 1 1
1.1. Specifications
Inputs:
• A (1-bit)
• B (1-bit)
• C (1-bit)
Outputs:
• Y0, Y1, Y2, Y3, Y4, Y5, Y6, Y7 (8-bit, active-low outputs)
Design Constraints:
• The decoder operates as a combinational circuit.
• Each output corresponds to a unique combination of the input bits.
Design Architecture for the 3-to-8 Decoder
The 3-to-8 decoder is a combinational circuit that takes three input bits and activates one of the
eight output lines based on the binary input combination.
Block Diagram:
design.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity decoder3to8 is
Port (
);
end decoder3to8;
begin
process(A)
begin
case A is
end case;
end process;
end Behavioral;
testbench.vhd
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
entity tb_decoder3to8 is
end tb_decoder3to8;
component decoder3to8
Port (
);
end component;
begin
process
begin
wait;
end process;
end testbench;
Testbench Setup
• Output Y is observed.
Expected Output:
The design was simulated in GHDL3.0.0. The waveform confirmed correct decoder output values
for different test cases.
The 3-to-8 Decoder was successfully implemented and verified. The simulation results matched the
expected truth table, confirming the correctness of the design. The design was simulated in
GHDL3.0.0. The waveform confirmed correct decoder output values for different test cases.
design.sv
module binary_decoder(
else begin
case(in)
endcase
end
end
endmodule
testbench.sv
`include "interface.sv"
`include "base_test.sv"
module tb_top;
bit clk;
bit reset;
initial begin
clk = 0;
reset = 1;
#5;
reset = 0;
end
initial begin
run_test("base_test");
end
initial begin
// Dump waves
$dumpfile("dump.vcd");
$dumpvars(0);
end
endmodule
base_test.sv
`uvm_component_utils(base_test)
env env_o;
super.new(name, parent);
endfunction
super.build_phase(phase);
endfunction
phase.raise_objection(this);
#100;
phase.drop_objection(this);
endtask
endclass
env.sv
`uvm_component_utils(env)
super.new(name, parent);
endfunction
super.build_phase(phase);
endfunction
endclass
agent.sv
class agent;
driver drv;
monitor mon;
generator gen;
mailbox gen_to_drv;
gen_to_drv = new();
gen = new(gen_to_drv);
endfunction
task run();
fork
drv.run();
mon.run();
gen.run();
join_any
endtask
endclass
driver.sv
class driver;
mailbox gen_to_drv;
this.gen_to_drv = gen_to_drv;
this.vif = vif;
endfunction
task run;
forever begin
transaction tr;
wait(!vif.reset);
tr = new();
@(posedge vif.clk);
gen_to_drv.get(tr);
vif.ip = tr.ip;
@(posedge vif.clk);
tr.out = vif.out;
end
endtask
endclass
transaction.sv
class transaction;
endclass
interface.sv
endinterface
my_pkg.sv
package my_pkg;
`include "uvm_macros.svh"
import uvm_pkg::*;
`include "transaction.sv"
`include "generator.sv"
`include "driver.sv"
`include "monitor.sv"
`include "scoreboard.sv"
`include "agent.sv"
`include "env.sv"
endpackage : my_pkg
monitor.sv
class monitor;
mailbox mon_to_sb;
int i=1;
this.vif = vif;
this.mon_to_sb = mon_to_sb;
endfunction
task run;
forever begin
transaction mon_tr;
wait(!vif.reset);
@(posedge vif.clk);
mon_tr = new();
mon_tr.ip = vif.ip;
@(posedge vif.clk);
mon_tr.out = vif.out;
mon_to_sb.put(mon_tr);
end
endtask
endclass
scoreboard.sv
class scoreboard;
int compare_cnt;
mailbox mon_to_sb;
int i,j;
this.mon_to_sb = mon_to_sb;
endfunction
task run;
forever begin
transaction tr;
tr = new();
mon_to_sb.get(tr);
j = tr.ip;
i = $pow(2,j);
if(i==tr.out)begin
$display("Matched: ip1 = %0d, out = %8b, expected out = %8b", tr.ip, tr.out,
i);
end
else begin
$display("NOT matched: ip1 = %0d, out = %8b, expected out = %8b", tr.ip,
tr.out, i);
end
compare_cnt++;
end
endtask
endclass
generator.sv
class generator;
int count;
mailbox gen_to_drv;
transaction tr;
this.gen_to_drv = gen_to_drv;
endfunction
task run;
repeat(count) begin
tr = new();
void'(tr.randomize());
gen_to_drv.put(tr);
end
endtask
endcl
The design was simulated in Cadence Xcelium 23.09. The waveform confirmed correct decoder
output values for different test cases.
The 3-to-8 Decoder was successfully verified using a UVM-based testbench. The testbench
architecture consisted of a driver, monitor, agent, environment, and scoreboard, ensuring a
structured verification approach. The stimulus was generated using UVM sequences, covering all
possible input cases.
• The UVM testbench successfully drove all input combinations and monitored the
corresponding output responses.
• The scoreboard compared the expected and actual outputs, and all test cases passed without
mismatches.
• The waveform analysis confirmed that the decoder correctly activated the expected output
for each input combination.
export SDC_FILE =
$(DESIGN_HOME)/$(PLATFORM)/$(DESIGN_NICKNAME)/constraint.sdc
#export CORE_ASPECT_RATIO = 1
#export CORE_MARGIN = 2
#export EQUIVALENCE_CHECK ?= 0
#export FASTROUTE_TCL =
$(DESIGN_HOME)/$(PLATFORM)/$(DESIGN_NICKNAME)/fastroute.tcl
export REMOVE_ABC_BUFFERS = 1
current_design decoder_3to8
Power Measurement
Area Measurement
• Utilization: 2%
Timing Information
Conclusion
In this report, the RTL code of the 3-to-8 decoder has been designed in Verilog. The code is
successfully verified using UVM with a 100% test case pass. The design is further processed in the
OpenROAD tool to generate its GDS using the GF180 platform. The generated layout consumes
108 nW power and occupies 4462 sq. µm area. There are no setup and hold violations.