0% found this document useful (0 votes)
5 views9 pages

Zero-Insertion Converter Design Guide

Uploaded by

elexiaelexir
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
5 views9 pages

Zero-Insertion Converter Design Guide

Uploaded by

elexiaelexir
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

what the circuit does

You watch a stream of bits (0s and 1s) coming in, one per clock tick.
You count how many 1s in a row you’ve recently seen.
 If you ever reach five 1s in a row, you let that 5th 1 pass normally.
 Then on the very next clock, you insert a 0 (force the output to 0), and raise a 1-cycle flag S=1 to
tell the source “pause a sec.”
 After that insert, you reset the counter to 0 and keep going.
 Any input 0 resets the streak to 0 (because the 1s streak was broken).
why do we insert on the next cycle?
If you inserted immediately at the 5th 1, you’d be removing that 5th 1, not inserting after it.
The spec says the 5th 1 passes, then you insert a 0 after that — so the inserted 0 happens on the next
clock.

why this is correct:

It encodes exactly the rule: when “stall state” is active (i.e., we’re at 5), force an output 0 and assert S.
Otherwise pass the input and manage the counter.

why: at cycle 6 the 5th 1 has just made the internal state become “5”; the next cycle (7) is the insertion.
Task 2
We convert the flowchart into a Finite State Machine (FSM).
states
Use 6 states, one per consecutive-1 count:
 C0, C1, C2, C3, C4, C5 where C5 is the special stall state (insert the 0 this cycle).
why: The machine’s entire memory is “how many 1s in a row have I seen (up to 5)?” That’s exactly 6
possibilities.

why this is correct:


 Arrows labeled in=1 count up the streak; any 0 arrow back to C0 breaks the streak; C5 is a one-
cycle sink that always returns to C0 (insert and reset).
why each row is right:

 Any 0 breaks the streak (Next=C0, out=0).


 On 1, you climb until C4→C5.
 In C5, you insert (out=0) and assert S (S=1) for that cycle, then reset (Next=C0).

why this encoding: It directly matches “how many 1s” → the logic becomes clean (compare to 5,
increment with saturation).
why: at cycle 6 the 5th 1 has just made the internal state become “5”; the next cycle (7) is the insertion.
why this matches code:
 The code exactly implements the DFFs and these combinational equations with simple assigns.

Task 3

Design (Verilog-2001 structural) — csc340teamproject.v


// csc340teamproject.v
// Zero-Insertion Converter (structural Verilog-2001)
// Counts consecutive 1's, inserts a 0 after the 5th one, asserts S for that cycle.

`timescale 1ns/1ps

// D flip-flop with async active-low reset.


module dff(input wire clk, input wire rst_n, input wire d, output reg q);
always @(posedge clk or negedge rst_n) begin
if (!rst_n) q <= 1'b0;
else q <= d;
end
endmodule
module csc340teamproject(
input wire clk,
input wire rst_n,
input wire in_bit, // X
output wire out_bit, // output bit
output wire S // stall flag (1 cycle after five 1s)
);
// State = 3-bit count of consecutive 1s: 000..101 (0..5)
wire [2:0] state;
wire [2:0] next_state;

// eq5 detects state==5 (101)


wire eq5;
assign eq5 = state[2] & ~state[1] & state[0];

// USE_INC means: we are allowed to increment (X=1 and not stalling)


wire use_inc;
assign use_inc = in_bit & ~eq5;

// Build a 3-bit incrementer (state + 1), then gate it by use_inc.


// sum0 toggles LSB, sum1 = Q1 ^ carry0, sum2 = Q2 ^ carry1.
wire sum0, carry0, sum1, carry1, sum2;
assign sum0 = ~state[0];
assign carry0 = state[0];
assign sum1 = state[1] ^ carry0;
assign carry1 = state[1] & carry0;
assign sum2 = state[2] ^ carry1;

// Next-state mux: if use_inc==1 take the incrementer; else reset to 000.


assign next_state[0] = use_inc ? sum0 : 1'b0;
assign next_state[1] = use_inc ? sum1 : 1'b0;
assign next_state[2] = use_inc ? sum2 : 1'b0;

// State register (3 DFFs)


dff ff0(.clk(clk), .rst_n(rst_n), .d(next_state[0]), .q(state[0]));
dff ff1(.clk(clk), .rst_n(rst_n), .d(next_state[1]), .q(state[1]));
dff ff2(.clk(clk), .rst_n(rst_n), .d(next_state[2]), .q(state[2]));

// Outputs
assign S = eq5; // assert during insertion cycle
assign out_bit = S ? 1'b0 : in_bit; // force 0 when stalling

endmodule

Outline of explanation for code:


why each part exists:
 DFFs store the 3-bit state (the count). Hardware remembers values only through flip-
flops.
 eq5 recognizes C5 (101) → that’s the stall cycle.
 use_inc is the rule “we only add 1 when X=1 and not stalling.”
 The incrementer is explicit (no behavioral +), keeping it structural and Verilog-2001
friendly.
 next_state mux: if we’re not allowed to increment, we reset to 0.
 outputs implement exactly S=(state==5) and out=X unless stall.

Testbench (Verilog-2001) — tb_csc340teamproject_v2001.v


// tb_csc340teamproject_v2001.v
// Verilog-2001 testbench with reset + real stimulus (no SystemVerilog)

`timescale 1ns/1ps

module tb_csc340teamproject_v2001;

reg clk, rst_n, in_bit;


wire out_bit, S;

// DUT
csc340teamproject DUT (
.clk(clk),
.rst_n(rst_n),
.in_bit(in_bit),
.out_bit(out_bit),
.S(S)
);

// Clock: 10 ns period
initial begin
clk = 1'b0;
forever #5 clk = ~clk;
end

// --- helper tasks to drive inputs --- //


task drive_bit; // drive one bit for one clock
input b;
begin
in_bit = b;
@(posedge clk);
end
endtask

task repeat_ones; // drive N consecutive 1's


input integer n;
integer i;
begin
for (i = 0; i < n; i = i + 1) drive_bit(1'b1);
end
endtask

task repeat_zeros; // drive N consecutive 0's


input integer n;
integer i;
begin
for (i = 0; i < n; i = i + 1) drive_bit(1'b0);
end
endtask

// Simulation control + stimulus


initial begin
// (Optional) waveform dump for external viewers
$dumpfile("[Link]");
$dumpvars(0, tb_csc340teamproject_v2001);

// Hold reset low, then release


rst_n = 1'b0;
in_bit = 1'b0;
repeat (3) @(posedge clk); // ~30 ns
rst_n = 1'b1; // RELEASE RESET
@(posedge clk);

// ----------- SEQ 1: quick warm-up (no insertion) ------------- //


drive_bit(1'b0);
drive_bit(1'b1);
drive_bit(1'b0);
drive_bit(1'b1);
drive_bit(1'b0);
drive_bit(1'b1);

// ----------- SEQ 2: force one insertion ---------------------- //


// 6 ones -> after 5th, the next cycle inserts 0 and S=1
repeat_ones(6);
repeat_zeros(3);

// ----------- SEQ 3: multiple insertions ---------------------- //


// 111111 000 111111 111111 000
repeat_ones(6); repeat_zeros(3);
repeat_ones(6); repeat_ones(6); repeat_zeros(3);

// ----------- SEQ 4: mixed edges ------------------------------ //


drive_bit(1'b1);
drive_bit(1'b0);
drive_bit(1'b1);
drive_bit(1'b1);
drive_bit(1'b0);
drive_bit(1'b1);
drive_bit(1'b0);
drive_bit(1'b0);
drive_bit(1'b1);

// pad some zeros for clean ending


repeat_zeros(5);

$display("Testbench completed.");
#50;
$finish;
end

endmodule

why this testbench is good for learning:


 It releases reset (many beginners forget, which freezes the DUT).
 It has clear sequences that prove the behavior: warm-up, single insertion, repeated insertions,
mixed.
 It uses simple Verilog-2001 tasks — no SystemVerilog strings/arrays — so it runs in any basic
simulator (and Vivado xsim).

Tcl helpers you can paste in the Tcl console

# show all signals


add_wave -r sim:/tb_csc340teamproject_v2001/*
# restart and run a nice long time
restart
run 2 us
# fit the whole run on the screen
wave zoom full
How Tasks 1 → 2 → 3 correlate (and match your waveforms)
 Task 1 (flowchart + timing): Defined the rules. In waveforms, you see the rule: out_bit mirrors
in_bit except on the insertion cycle, where out_bit=0 and S=1.
 Task 2 (FSM + table + equations): Turned rules into states C0..C5, transitions, and equations
for S, out, and next_state. In waveforms, each S=1 aligns with state==C5, and you can even
add internal state bits to your wave to watch 000→…→101→000.
 Task 3 (code + sim): Implemented the equations with flip-flops and combinational logic; the
testbench shows the exact insert behavior; your screenshots already match this: S spikes for
one clock and out_bit is 0 right there, exactly as designed.
Conclusion
Through Tasks 1–3, we moved step by step from conceptual sketches to a formal FSM design and finally
to simulation in Vivado. The flowchart and timing diagrams in Task 1 laid the foundation by predicting
how the circuit should behave. In Task 2, we transformed those predictions into a state machine with a
state table, logic equations, and block diagrams, ensuring every path was logically consistent. Task 3
confirmed our work: the Verilog code and simulation waveforms matched our earlier sketches exactly,
with the output pulse S appearing only after five consecutive 1’s as designed. This process shows how
careful planning, visualization, and step-by-step verification turn abstract ideas into working digital
systems.

You might also like