Created
February 28, 2012 11:54
-
-
Save sora/1932114 to your computer and use it in GitHub Desktop.
stack
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
`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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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