Skip to content

Instantly share code, notes, and snippets.

@sora
Created February 28, 2012 11:54
Show Gist options
  • Save sora/1932114 to your computer and use it in GitHub Desktop.
Save sora/1932114 to your computer and use it in GitHub Desktop.
stack
`define dbg 1
module stack #(
parameter width = 96, // default item width
parameter depth = 10922, // default stack depth
parameter log2depth = 14 // default stack depth's address range
)(
input CLK,
input RST,
input push,
input pop,
input [width-1:1] push_item, // assume that item type is ASCII
output reg[width-1:1] pop_item,
output reg empty,
output reg full,
// When err is True, stack is overflow or underflow or both command flag is True
output reg err
);
// Xilinx ISE 13.4 (Verilog-2001) doesn't support $clog2
function integer clog2;
input integer value;
begin
value = value - 1;
for (clog2 = 0; value > 0; clog2 = clog2 + 1)
value = value >> 1;
end
endfunction
reg[width-1:0] _stack[log2depth-1:0]; // a register that holds unused memory
reg[log2depth-1:0] stack_ptr = 0; // stack pointer
// full
always @*
full <= (stack_ptr == depth - 1) ? 1 : 0;
// empty
always @*
empty <= (stack_ptr) ? 0 : 1;
// pop_item
always @* begin
if (pop && stack_ptr) begin
if (stack_ptr == depth - 1)
pop_item <= _stack[stack_ptr];
else
pop_item <= _stack[stack_ptr-1];
end else
pop_item <= {width{1'bz}};
end
// err
always @(posedge CLK) begin
if (RST)
err <= 0;
else begin
if (push && pop)
err <= 1; // error: both command is True
else if (pop && empty)
err <= 1; // error: stack underflow
else if (push && full)
err <= 1; // error: stack overflow
else
err <= 0;
end
end
// stack_ptr
always @(posedge CLK) begin
if (RST)
stack_ptr <= 0;
else begin
if (pop && !empty) begin
stack_ptr <= stack_ptr - 1;
end else if (push && !full) begin
stack_ptr <= stack_ptr + 1;
_stack[stack_ptr] <= push_item;
end
end
end
endmodule
// iverilog -s sim tb_stack.v stack.v
`define STEP 2
`define dbg 1
module sim();
parameter stack_width = 8 * 8 + 1;
parameter stack_depth = 8;
parameter stack_log2depth = 3;
reg tb_push;
reg tb_pop;
reg[stack_width-1:1] tb_push_item;
wire CLK;
wire RST;
wire[stack_width-1:1] tb_pop_item;
wire tb_empty;
wire tb_full;
wire tb_err;
clock clock (
.CLK(CLK),
.RST(RST)
);
stack #(
.width(stack_width),
.depth(stack_depth),
.log2depth(stack_log2depth)
) stack (
.CLK(CLK),
.RST(RST),
.push(tb_push),
.pop(tb_pop),
.push_item(tb_push_item),
.pop_item(tb_pop_item),
.empty(tb_empty),
.full(tb_full),
.err(tb_err)
);
initial begin
$dumpfile("tb_stack.vcd");
$dumpvars(0, sim.stack);
end
initial begin
#100 tb_push = 1; tb_pop = 0; tb_push_item = "abc";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "bcd";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "cde";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "def";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "efg";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "fgh";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "ghi";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "hij";
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 1; tb_pop = 0; tb_push_item = "123";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "234";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "345";
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 0; tb_pop = 1;
#100 tb_push = 1; tb_pop = 0; tb_push_item = "123";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "234";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "345";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "345";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "345";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "345";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "345";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "345";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "345";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "345";
#100 tb_push = 1; tb_pop = 0; tb_push_item = "345";
$finish();
end
always @(posedge CLK) begin
if (RST) begin
tb_push <= 0;
tb_pop <= 0;
tb_push_item <= {stack_width{1'bz}};
end
else begin
if (tb_push) begin
tb_push <= 0;
$display(" Pushed: %s", tb_push_item);
end
if (tb_pop) begin
tb_pop <= 0;
$display(" Popped:");
end
if (tb_push_item) begin
tb_push_item <= {stack_width{1'bz}};
end
if (tb_pop_item)
$display("POPItem: %s", tb_pop_item);
if (tb_err)
$display("ERROR: stack overflow or underflow");
// if (tb_full)
// $display("stack is full");
// if (tb_empty)
// $display("stack is empty");
end
end
endmodule // sim()
module clock (
output reg CLK,
output reg RST
);
initial CLK = 0;
initial RST = 0;
always #(`STEP / 2) begin
CLK <= ~CLK;
RST <= 0;
end
endmodule // clock()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment