coffee vending machine simulation in verilog with test bench issue - verilog

I have written a verilog code for a simple coffee vending machine with inputs
25ps,50ps,75ps and 1
as
"00","01","10" and "11"
respectively. Coffee cost is 1 rs. If more than 1rs is inserted, the balance will be returned. That balance will be
01, 10, 11
as
25ps, 50ps, 1rs
respectively. I simulate this without test bench. simulation takes double clock pulse for output.(when i put 25 ps 8 times or 8 clock pulses is required for getting output. expected clock pulse is 4). Why this is happens? and also i didn't get output when using the test bench.
please help me to correct the test bench and my programme. Is clock frequency divider is necessary while doing the programme in fpga board to see output? It is working as expected when i programmed into fpga board.Im using Xilinx vivado 2015.2 tool and zynq board.Please help me to solve these issues
//programme
module main(
input clk,
input rst,
input [1:0] money,
output coffee,
output [1:0] balance
);
reg coff;
reg [1:0] bal;
reg [2:0] pr_st;
reg [2:0] nx_st;
parameter [2:0] A=3'b000;
parameter [2:0] B=3'b001;
parameter [2:0] C=3'b010;
parameter [2:0] D=3'b011;
parameter [2:0] E=3'b100;
parameter [2:0] F=3'b101;
parameter [2:0] G=3'b110;
parameter [2:0] H=3'b111;
always # (posedge clk or posedge rst)
begin
if(rst)
pr_st <= A;
else
pr_st <= nx_st;
end
always #(posedge clk)
begin
case(pr_st)
A : if(money == 2'b00) // input money is 25ps
begin
nx_st <= B;
end
else if(money == 2'b01) // input money is 50ps
begin
nx_st <= C;
end
else if(money == 2'b10) // input money is 75ps
begin
nx_st <= D;
end
else if(money == 2'b11)
begin
nx_st <= E;
end
B : if(money == 2'b00)
begin
nx_st <= C;
end
else if(money == 2'b01)
begin
nx_st <= D;
end
else if(money == 2'b10)
begin
nx_st <= E;
end
else if(money == 2'b11)
begin
nx_st <= F;
end
C : if(money == 2'b00)
begin
nx_st <= D;
end
else if(money == 2'b01)
begin
nx_st <= E;
end
else if(money == 2'b10)
begin
nx_st <= F;
end
else if(money == 2'b11)
begin
nx_st <= G;
end
D : if(money == 2'b00)
begin
nx_st <= E;
end
else if(money == 2'b01)
begin
nx_st <= F;
end
else if(money == 2'b10)
begin
nx_st <= G;
end
else if(money == 2'b11)
begin
nx_st <= H;
end
E : nx_st <= A;
F : nx_st <= A;
G : nx_st <= A;
H : nx_st <= A;
default : nx_st <= A;
endcase
end
//output logic
always #( posedge clk or pr_st)
begin
case(pr_st)
A: begin
coff <= 1'b0;
bal <= 2'b00;
end
B: begin
coff <= 1'b0;
bal <= 2'b00;
end
C: begin
coff <= 1'b0;
bal <= 2'b00;
end
D: begin
coff <= 1'b0;
bal <= 2'b00;
end
E: begin
coff <= 1'b1;
bal<= 2'b00;
end
F: begin
coff <= 1'b1;
bal <= 2'b01;
end
G: begin
coff <= 1'b1;
bal <= 2'b10;
end
H: begin
coff <= 1'b1;
bal <= 2'b11;
end
default : begin
off <=1'b0;
bal <= 2'b00;
end
endcase
end
assign coffee = coff;
assign balance = bal;
endmodule
//test bench
module tb_main(
);
reg clk;
reg rst;
reg [1:0] money;
wire coffee;
wire [1:0] balance;
main dut( clk, rst, money, coffee, balance);
always
begin
#200 clock = ~clk;
end
initial
begin
rst = 1'b1;
#100 rst = 1'b0;
money = 2'b00; // putting 25ps four times to get coffee
#400 money = 2'b01; //putting 50ps two times to get coffee
#200 money = 2'b10;// putting 75ps two times to get coffee
#200 money = 2'b11;// putting 1 rs single time to g
#100 money = 2'b01; // putting 1st 25ps and 50ps i n second clock cycle
#100 money = 2'b10;
#200
$finish
end
endmodule

You need to initialize your clock signal to a known value in the testbench. You should speed up the clock because your money input changes faster than the clock:
initial clk = 0;
always begin
#10 clk = ~clk;
end

Related

Module instantiation with the "number sign"

I have the main module with FIFO stuff.
Here it is:
module syn_fifo #(
parameter DATA_WIDTH = 8, // inpit capacity
parameter DATA_DEPTH = 8 // the depth of the FIFO
)
(
input wire clk,
input wire rst,
// Write_______________________________________________
input wire [DATA_WIDTH-1:0]din, // the input data
input wire wren, // Write anable
output wire full,
// Read________________________________________________
output wire [DATA_WIDTH-1:0]dout, // The output data
input wire rden, // Read enable
output wire empty
);
integer q_size; // The queue size(length)
integer golova; // The queue beginning
integer hvost; // The end of queue
reg [DATA_WIDTH-1:0]fifo[DATA_DEPTH-1:0];
assign full = (q_size == DATA_DEPTH) ? 1'b1: 1'b0; // FIFO is full
/*
True { full = (q_size==DATA_TEPTH) = 1 }, then wire "full" goes to "1" value
False { full = (q_size==DATA_TEPTH) = 0 }, then wire "full" goes to "0" value
*/
assign empty = (golova == hvost); // FIFO is empty
assign dout = fifo[hvost]; // FWFT (other write mode)
integer i;
//___________(The queue fullness)___________________
always #(posedge clk or posedge rst)
begin
if (rst == 1'b1)
begin
for (i = 0; i < DATA_DEPTH; i = i + 1) // incrementing the FIFO
fifo[i] <= 0; // Resetting the FIFO
golova <= 0; // Resetting the queue start variable
end
else
begin //Write_______________________________________
if (wren && ~full)
begin
fifo[golova] <= din; // putting data in to the golova
if (golova == DATA_DEPTH-1) // restrictions for the queue beginning
golova <= 0; // Reset the beginning
else
golova <= golova + 1; // other occurence incrementing
end
end
end
//Reading
always #(posedge clk or posedge rst)
begin
if (rst == 1'b1)
begin
hvost <= 0;
end
else
begin
if (rden && !empty)
/*for staying inside the queue limits - make the check of non equality of the "hvost" & "queue size"*/
begin
if (hvost == DATA_DEPTH-1) // if hvost = DATA_DEPTH-1, then
hvost <= 0; // Reset hvost
else
hvost <= hvost + 1;
end
end
end
always # (posedge clk)
begin
if (rst == 1'b1) begin
q_size <= 0;
end
else
begin
case ({wren && ~full, rden && ~empty} )
2'b01: q_size <= q_size + 1; // RO
2'b10: q_size <= q_size - 1; // WO
default: q_size <= q_size; // read and write at the same time
endcase
end
end
endmodule
Also i've got the testbench module down delow:
`timescale 1ns / 1ps
module fifo_tb();
localparam CLK_PERIOD = 10;
reg clk;
reg rst;
always begin
clk <= 1'b0;
#(CLK_PERIOD / 2);
clk <= 1'b1;
#(CLK_PERIOD / 2);
end
localparam DATA_WIDTH = 8;
localparam DATA_DEPTH = 4;
reg [DATA_WIDTH-1:0]din;
reg wren;
reg rden;
wire [DATA_WIDTH-1:0]dout;
wire empty;
wire full;
wire wr_valid;
wire rd_valid;
task write;
input integer length;
begin
if (length) begin
#(posedge clk);
wren <= 1'b1;
while (length) begin
#(posedge clk);
if (wr_valid) begin
length <= length - 1;
if (length == 1) begin
wren <= 1'b0;
end
end
end
end
end
endtask
task read;
input integer length;
begin
if (length) begin
#(posedge clk);
rden <= 1'b1;
while (length) begin
#(posedge clk);
if (rd_valid) begin
length <= length - 1;
if (length == 1) begin
rden <= 1'b0;
end
end
end
end
end
endtask
initial begin
rst <= 1'b0;
wren <= 1'b0;
rden <= 1'b0;
#50;
rst <= 1'b1;
#50;
rst <= 1'b0;
#200;
/* Test Start */
//write(4);
//read(4);
/* Test Stop */
#1000;
$finish;
end
assign wr_valid = wren & ~full;
assign rd_valid = rden & ~empty;
always #(posedge clk) begin
if (rst == 1'b1) begin
din <= 0;
end else begin
if (wr_valid == 1'b1) begin
din <= din + 1;
end
end
end
// write?
always begin
#400;
write(5);
#15;
write(7);
#25;
write(3);
#15;
write(9);
#15;
write(1);
#10000;
end
// read?
always begin
#420;
read(3);
#37;
read(13);
#21;
read(7);
#15;
read(9);
#15;
read(4);
#20;
read(7);
#10000;
end
initial begin
$dumpfile("test.vcd");
$dumpvars(0,fifo_tb);
end
syn_fifo #(.DATA_WIDTH(DATA_WIDTH),
.DATA_DEPTH(DATA_DEPTH)) dut ( .clk(clk),
.rst(rst),
.din(din),
.wren(wren),
.full(full),
.dout(dout),
.rden(rden),
.empty(empty));
endmodule
Trying to compile all of it with iVerilog + GTKwave + Win10 by next command:
C:\Program Files\iverilog\bin>iverilog -o fifo.v fifo_tb.v
The compiler gives me the next message:
fifo_tb.v:138:error: Unknown module type:syn_fifo
2 error(s) during elaboration.
These modules were missing:syn_fifo referenced 1 times
At the necessary line "138" maybe the main mistake is covered by the "Number sign" in module instantiation?
/*132|*/ initial begin
/*133|*/ $dumpfile("test.vcd");
/*134|*/ $dumpvars(0,fifo_tb);
/*135|*/ end
/*136|*/
/*137|*/ syn_fifo #(.DATA_WIDTH(DATA_WIDTH),
/*138|*/ .DATA_DEPTH(DATA_DEPTH)) dut ( .clk(clk),
/*139|*/ .rst(rst),
/*140|*/ .din(din),
/*141|*/ .wren(wren),
/*142|*/ .full(full),
/*143|*/ .dout(dout),
/*144|*/ .rden(rden),
/*145|*/ .empty(empty));
/*146|*/
/*147|*/ endmodule
I'm not shure of that.
Seems like you are indicating fifo.v to be your output file, try:
iverilog -o syn_fifo.tb -s fifo_tb fifo_tb.v fifo.v
-o -> output file
-s -> top module (in this case, the test one)
(after everything, include all the files)
Then, to run it:
vvp syn_fifo.tb
Thank you, dear #m4j0rt0m
I just forgot to type in the output file name at the CMD window. Was very exhausted so haven't noticed such a detail)))
Usually it looks like:
iverilog -o OUTPUT_FILE_NAME fifo_tb.v fifo.v
And also I tried your advice, and it's finally done!

How to change the code. verilog testbench code

I make a design for an adder but the result is wrong.
module FMUL(CLK, St, F1, E1, F2, E2, F, V, done);
input CLK;
input St;
input [3:0] F1;
input [3:0] E1;
input [3:0] F2;
input [3:0] E2;
output[6:0] F;
output V;
output done;
reg[6:0] F;
reg done;
reg V;
reg[3:0] A;
reg[3:0] B;
reg[3:0] C;
reg[4:0] X;
reg[4:0] Y;
reg Load;
reg Adx;
reg SM8;
reg RSF;
reg LSF;
reg AdSh;
reg Sh;
reg Cm;
reg Mdone;
reg[1:0] PS1;
reg[1:0] NS1;
reg[2:0] State;
reg[2:0] Nextstate;
initial
begin
State = 0;
PS1 = 0;
NS1 = 0;
Nextstate=0;
end
always #(PS1 or St or Mdone or X or A or B)
begin : main_control
Load = 1'b0;
Adx = 1'b0;
NS1 = 0;
SM8 = 1'b0;
RSF = 1'b0;
LSF = 1'b0;
V = 1'b0;
F = 7'b0000000;
done = 1'b0;
case (PS1)
0 :
begin
F = 7'b0000000;
done = 1'b0;
V = 1'b0;
if(St == 1'b1)
begin
Load = 1'b1;
NS1 = 1;
end
end
1 :
begin
Adx = 1'b1;
NS1 = 2;
end
2 :
begin
if(Mdone == 1'b1)
begin
if(A==0)
begin
SM8 = 1'b1;
end
else if(A == 4 & B == 0)
begin
RSF = 1'b1;
end
else if (A[2] == A[1])
begin
LSF = 1'b1;
end
NS1 = 3;
end
else
begin
NS1 = 2;
end
end
3 : begin
if(X[4] != X[3])
begin
V = 1'b1;
end
else
begin
V = 1'b0;
end
done = 1'b1;
F = {A[2:0],B};
if(St==1'b0)
begin
NS1 = 0;
end
end
endcase
end
always #(State or Adx or B)
begin : mul2c
AdSh = 1'b0;
Sh = 1'b0;
Cm = 1'b0;
Mdone = 1'b0;
Nextstate = 0;
case(State)
0 :
begin
if(Adx==1'b1)
begin
if((B[0]) == 1'b1)
begin
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = 1;
end
end
1,2 :
begin
if((B[0])==1'b1)
begin
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = State + 1;
end
3:
begin
if((B[0])==1'b1)
begin
Cm = 1'b1;
AdSh = 1'b1;
end
else
begin
Sh = 1'b1;
end
Nextstate = 4;
end
4:
begin
Mdone = 1'b1;
Nextstate = 0;
end
endcase
end
wire [3:0] addout;
assign addout = (Cm == 1'b0)? (A+C) : (A-C);
always #(posedge CLK)
begin : update
PS1 <= NS1;
State <= Nextstate;
if(Load == 1'b1)
begin
X <= {E1[3], E1};
Y <= {E2[3], E2};
A <= 4'b0000;
B <= F1;
C <= F2;
end
if(Adx == 1'b1)
begin
X <= X+Y;
end
if(SM8 == 1'b1)
begin
X <= 5'b11000;
end
if(RSF == 1'b1)
begin
A <= {1'b0, A[3:1]};
B <= {A[0], B[3:1]};
X <= X+1;
end
if(LSF == 1'b1)
begin
A <= {A[2:0], B[3]};
B <= {B[2:0], 1'b0};
X <= X+31;
end
if(AdSh == 1'b1)
begin
A <= {(C[3]^Cm), addout[3:1]};
B <= {addout[0], B[3:1]};
end
if(Sh == 1'b1)
begin
A <= {A[3], A[3:1]};
B <= {A[0], B[3:1]};
end
end
endmodule
test bench.
module tb_FMUL();
wire[6:0] F;
wire done;
wire V;
reg[3:0] A;
reg[3:0] B;
reg[3:0] C;
reg[4:0] X;
reg[4:0] Y;
reg Load;
reg Adx;
reg SM8;
reg RSF;
reg LSF;
reg AdSh;
reg Sh;
reg Cm;
reg Mdone;
reg[1:0] PS1;
reg[1:0] NS1;
reg[2:0] State;
reg[2:0] Nextstate;
reg CLK;
reg St;
reg [3:0] F1;
reg [3:0] E1;
reg [3:0] F2;
reg [3:0] E2;
FMUL u0(CLK, St, F1, E1, F2, E2, F, V, done);
always
begin
#10 CLK <= ~CLK;
end
initial
begin
#100 F1 = 2.125;
E1 = 5; F2 = 5.1; E2 = 1; St=0;
#100 F1 = 1.125;
E1 = 5; F2 = 2.1; E2 = 2; St=0;
#100 F1 = 5.125;
E1 = 5; F2 = 3.1; E2 = 3; St=0;
end
endmodule
The simulation results waveform.
enter image description here
I refer to the book.There is no code test bench.
So I made. But did't operate.
also CLK not is not changed.
please review the testbench code.
You have (at least) two problems:
Your clock needs to be initialised (eg to 1'b0):
initial CLK = 1'b0;
The initial value of any wire or reg in Verilog is 1'bx; ~1'bx is 1'bx; so CLK remains at 1'bx.
Your simulation doesn't stop. I added a call to $finish in the main initial block.
https://www.edaplayground.com/x/r4U

Verilog code for shift and add multiplier

Good day guys, I'm created a Shift - And - Add multiplier. I'm confused on why my output is wrong and always at 85. Is it something with the Test bench ? It's working by the way.
new1.v
`define M ACC[0]
module mult4X4 (Clk, St, Mplier, Mcand, Done, Result);
input Clk,St;
input [3:0] Mplier, Mcand;
output Done;
output [7:0] Result;
reg [3:0] State;
reg [8:0] ACC;
initial
begin
State = 0;
ACC = 0;
end
always #(posedge Clk)
begin
case (State)
0:
begin
if(St == 1'b1)
begin
ACC[8:4] <= 5'b00000 ;
ACC[3:0] <= Mplier ;
State <= 1;
end
end
1,3,5,7 :
begin
if(`M==1'b1)
begin
ACC[8:4] <= {1'b0, ACC[7:4]} + Mcand ;
State <= State +1;
end
else
begin
ACC <= {1'b0, ACC[8:1]};
State <= State + 2;
end
end
2,4,6,8 :
begin
ACC <= {1'b0, ACC[8:1]};
State <= State +1;
end
9:
begin
State <= 0;
end
endcase
end
assign Done = (State == 9) ? 1'b1 : 1'b0 ;
assign Result = (State == 9) ? ACC[7:0] : 8'b01010101;
endmodule
tb_new1.v
module tb_mult4X4;
reg Clk,St,nReset;
reg [3:0] Mplier;
reg [3:0] Mcand;
wire Done;
wire [7:0] Result;
mult4X4 UUT (Clk,St,Mplier,Mcand,Done,Result);
initial begin
$dumpfile ("mult4X4.vpd");
$dumpvars;
end
initial
Clk = 0;
always
#5 Clk =~Clk;
initial begin
nReset = 0;
St = 0;
Mcand = 4'b1101;
Mplier = 4'b1011;
#10
nReset = 1;
St = 1;
Mcand = 4'b1111;
Mplier = 4'b1001;
#10
Mcand = 4'b0101;
Mplier = 4'b1010;
#10
Mcand = 4'b1111;
Mplier = 4'b1111;
#10
Mcand = 4'b1101;
Mplier = 4'b1010;
$finish;
end
endmodule
I ran though the code so many times and everything seems to be following my FSM. Can anyone please point out where went wrong. Really confused on this one
#10 is way to short. Your RTL requires 10 clocks to complete but you change the input every clock (half clk is #5).
Use #100 or better yet #(posedge Done); (which makes the test-bench to wait for done regardless the number of clocks that is required).

Event counter in verilog

i'm a verilog beginner, i'm try to write a "event counter" on verilog.... this is my code, but it work only with "period" set to 16'b0000000000000001, if try set period to 16'b0000000000001000, result(out_event) is always '0'.
Someone can help me to fix it ?
module mymodule(
input wire clk,
input wire enable,
input wire reset,
input wire [15:0] period,
input wire in_event,
output reg out_event
);
reg en = 1'b0;
reg re = 1'b0;
reg [15:0] count = 16'b0000000000000000;
always #(posedge clk) en <= enable;
always #(posedge clk) re <= reset;
always #(in_event)begin
if(in_event == 1'b1)begin
if(re)begin
count <= 0 ;
out_event <= 1'b0;
end else begin
if(en) begin
if(count == period-1)begin
out_event <= 1'b1;
count <= 0;
end else begin
count <=count + 1;
out_event <= 1'b0;
end
end else begin
out_event <= 1'b0;
end
end
end else begin
out_event <= 1'b0;
end
end
endmodule
thanks in advance
The counter counts number of posedge of in_event wire. So, can you use #(posedge in_event)?
I simulated your code, providing a testbench to it.
I do not have much knowledge about hardware synthesis, but personally, I would suggest to write your logic based on edge/level of clock.
This code works completely well. Have a look at this link.
You can configure various values of period in testbench, hope this will be helpful.
I came up with a test bench and the design for your problem and it works.
`timescale 1s / 1s
module TB();
reg clk;
reg enable;
reg reset;
reg [15:0] period;
wire out_event;
wire [15:0] counter;
initial begin
clk = 1'b0;
forever begin
#1 clk = ~clk;
end
end
stack_exch_code test (.clk(clk),
.enable(enable),
.reset(reset),
.period(period),
.out_event(out_event),
.tb_counter(counter)
);
integer i;
initial
begin
#(negedge clk) reset = 1'b1; enable = 1'b0; period = 16'h0000;
#(negedge clk) reset = 1'b0; enable = 1'b1; period = 16'h00FF;
for (i = 0 ; i < 500 ; i = i + 1) begin
#(negedge clk) period = period - 1;
#(posedge clk) $display ("Period = %h , Counter = %h, Out_Event = %b ", period, counter, out_event);
end
#(negedge clk) $finish;
end
endmodule //TB
module stack_exch_code (input clk,
input enable,
input reset,
input [15:0] period,
//input inevent,
output reg out_event,
output [15:0] tb_counter
);
// initialization doesnt matter in hardware, its not C or C++
reg en;
reg re;
reg [15:0] count;
always # (posedge clk) begin
re <= reset;
en <= enable;
end
always # (posedge clk) begin
if (re) begin
count <= 16'h0000;
out_event <= 1'b0;
end
else if (en) begin
if ((count == period - 1) && !(period == 16'h0000)) begin
out_event <= 1'b1;
count <= 16'h0000;
end
else if (!(period == 16'h0000)) begin
count <= count + 1;
out_event <= 1'b0;
end
else if (period == 16'h0000)
out_event <= 1'b0;
end
end
assign tb_counter = count;
endmodule //stack_exch_code

Creating pulses of different width

I have written following code which produces pulse of different width.I want the code to produce a single pulse according to select line.
If select line is
00 pulse width = 1 us ,
01 pulse width = 10 us
. .
11 pulse width = 1000 us
The input clock is of 10 Mhz.
But according to code I am getting continuous pulse if I don't provide any other value of selection line.How can I achieve only one pulse?
module pulse(input wire [1:0] sel , //selection lines s1 s0
input clk,
input rst_n,
output reg flag, //for checking conditions
output reg [13:0] Q, // output of 14 bit counter
output reg pulse, //output pulse
output reg count); //also for checking conditions
wire flag_d , count_d;
assign flag_d = ( (sel == 2'b00 | sel == 2'b01 | sel == 2'b10 | sel == 2'b11) && count == 1'b0)? 1'b1 : flag;
assign count_d = ( (sel == 2'b00 | sel == 2'b01 | sel == 2'b10 | sel == 2'b11) && count == 1'b0)? 1'b1 : count;
always #(posedge clk , negedge rst_n)
begin
if(!rst_n)
begin
Q <= 14'h0;
count <= 1'b0;
pulse <= 1'b0;
flag <= 1'b0;
end
else
begin
flag <= flag_d;
count <= count_d;
if(flag)
begin
case(sel)
2'b00: Q <= 14'd11;//count from 11 to 1
2'b01: Q <= 14'd101;//count from 101 to 1
2'b10: Q <= 14'd1001;//count from 1001 to 1
2'b11: Q <= 14'd10001;//count from 10001 to 1
default: Q <= 14'd0;
endcase
flag <= 1'b0;
end
else
begin
if(Q != 14'h1 && Q != 14'h0)
begin
Q <= Q - 14'h1;
pulse <= 1'b1;
end
else
begin
pulse <= 1'b0;
count <= 1'b0;
end
end
end
end
endmodule
Is this code in a good coding style considering the synthesis and hardware of the circuit? if not than what changes I should apply?..
I couldn't figure out the point of flag_d and count_d. Also ( (sel == 2'b00 | sel == 2'b01 | sel == 2'b10 | sel == 2'b11) && count == 1'b0) simplifies to (count == 1'b0). sel should not be Xs or Zs.
I think you want something more like the following:
reg [13:0] next_Q;
always #* begin
if (Q==0) begin
case(sel)
2'b00 : next_Q = 14'd10;
2'b01 : next_Q = 14'd100;
2'b10 : next_Q = 14'd1000;
2'b11 : next_Q = 14'd10000;
endcase
end
else begin
next_Q = Q - 1;
end
end
always #(posedge clk, negedge rst_n) begin
if (!rst_n) begin
pulse <= 1'b0;
Q <= 14'd0;
end
else begin
// if (Q==0) pulse <= !pulse; // high and low pulse will have equal if sel is constant
pulse <= (Q!=0); // or high pulse based on sel, low is one clk
Q <= next_Q;
end
end
working example: http://www.edaplayground.com/x/GRv
module pulse(input wire [1:0] sel, // No need for the sel to be wire
input clk,
input rst_n,
output reg [13:0] Q,
output reg pulse,
input input_stb, // Input is valid
input output_ack,
output output_stb,
output input_ack); // 2 Flag model
reg s_input_ack ;
reg s_output_stb;
parameter get_inputs = 4'd0,
counter = 4'd1;
always #(posedge clk , negedge rst_n)
begin
case (state)
get_inputs:
s_input_ack <= 1;
if (s_input_ack && input_a_stb)
begin
s_input_ack <= 0;
case(sel)
00: Q <= 14'd11;//00000000001010;
01: Q <= 14'd101;//00000001100100;
10: Q <= 14'd1001;//00001111101000;
11: Q <= 14'd10001;//10011100010000;
default: Q <= 14'd0;
endcase
state <= counter;
end
counter:
begin
s_output_stb <= 1;
if (s_output_stb && output_z_ack)
begin
s_output_stb <= 0;
if(Q != 14'h1 && Q != 14'h0)
begin
Q <= Q - 1'b1;
pulse <= 1'b1;
end
else
begin
pulse <= 1'b0;
end
end
state <= get_inputs;
end
endcase
if(!rst_n)
begin
Q <= 14'h0;
pulse <= 1'b0;
s_input_ack <= 0;
s_output_stb <= 0;
end
assign input_ack = s_input_ack;
assign output_stb = s_output_stb;
end
endmodule
*Still needs work , add registers and necessary signals accordingly. Will edit at a later point in time

Resources