I’m working on a homework assignment for my Digital IC Design class, where I need to design and implement a Max-Priority Queue (MPQ) circuit. The circuit should handle specific queue operations including Build_Queue, Extract_Max, Increase_Value, and Insert_Data, and then write results to RAM.
Here’s a brief overview of the specifications:
Inputs: clk, rst, data (8-bit), data_valid, cmd (3-bit), index (8-bit), value (8-bit), cmd_valid.
Outputs: RAM_valid, RAM_A (8-bit), RAM_D (8-bit), busy, done.
I have written the following Verilog code for the MPQ module, but I’m having some issues with the implementation, particularly with the state transitions and ensuring the correct timing for RAM operations.
task MAX_HEAPIFY(input integer i);
integer l, r, largest, temp;
begin
l = 2*i + 1;
r = 2*i + 2;
if (l < size && heap[l] > heap[i])
largest = l;
else
largest = i;
if (r < size && heap[r] > heap[largest])
largest = r;
if (largest != i) begin
temp = heap[i];
heap[i] = heap[largest];
heap[largest] = temp;
MAX_HEAPIFY(largest);
end
end
endtask
task BUILD_QUEUE;
integer i;
begin
for (i = size/2 - 1; i >= 0; i = i - 1) begin
MAX_HEAPIFY(i);
end
end
endtask
task EXTRACT_MAX;
begin
if (size < 1) begin
$display("heap underflow");
end else begin
heap[0] = heap[size - 1];
size = size - 1;
MAX_HEAPIFY(0);
end
end
endtask
task INCREASE_VALUE(input integer idx, input [7:0] val);
integer parent, temp;
begin
if (val < heap[idx]) begin
$display("new value is smaller than current value");
end else begin
heap[idx] = val;
while (idx > 0 && heap[(idx - 1) / 2] < heap[idx]) begin
parent = (idx - 1) / 2;
temp = heap[idx];
heap[idx] = heap[parent];
heap[parent] = temp;
idx = parent;
end
end
end
endtask
task INSERT_DATA(input [7:0] val);
begin
if (size < 255) begin
size = size + 1;
heap[size - 1] = 8'h00;
INCREASE_VALUE(size - 1, val);
end else begin
$display("heap overflow");
end
end
endtask
always @(posedge clk or posedge rst) begin
if (rst) begin
size <= 8'd0;
state <= IDLE;
RAM_valid <= 1'b0;
busy <= 1'b1;
done <= 1'b0;
end else begin
case (state)
IDLE: begin
busy <= 1'b0;
done <= 1'b0;
RAM_valid <= 1'b0;
if (cmd_valid) begin
busy <= 1'b1;
case (cmd)
3'b000: state <= BUILD;
3'b001: state <= EXTRACT;
3'b010: state <= INCREASE;
3'b011: state <= INSERT;
3'b100: state <= WRITE;
default: state <= IDLE;
endcase
end
end
BUILD: begin
if (data_valid) begin
heap[size] <= data;
size <= size + 1;
end else begin
BUILD_QUEUE;
state <= DONE;
end
end
EXTRACT: begin
EXTRACT_MAX;
state <= WRITE;
end
INCREASE: begin
INCREASE_VALUE(index, value);
state <= WRITE;
end
INSERT: begin
INSERT_DATA(value);
state <= WRITE;
end
WRITE: begin
if (size > 0) begin
RAM_valid <= 1'b1;
RAM_A <= size - 1;
RAM_D <= heap[size - 1];
state <= DONE;
end else begin
state <= DONE;
end
end
DONE: begin
done <= 1'b1;
busy <= 1'b0;
state <= IDLE;
end
default: state <= IDLE;
endcase
end
end
Terry Wei is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.