1

Implement CPU "cycle" decoder

This commit is contained in:
2023-03-30 00:21:01 +02:00
parent c2f92ccb66
commit 88a72358f7
2 changed files with 131 additions and 0 deletions

47
Decoder.sv Normal file
View File

@ -0,0 +1,47 @@
`default_nettype none
module Decoder(
input var logic clock,
input var logic reset,
output var logic fetch,
output var logic decode,
output var logic execute,
output var logic writeback
);
var logic was_reset;
var logic setvalue;
var logic[1:0] reset_val;
var logic[1:0] mode;
Counter #(.WIDTH(2)) mode_cnt(
.clock(clock),
.reset(0),
.decrement(0),
.setvalue(setvalue),
.valuein(reset_val),
.valueout(mode)
);
always @(posedge clock or posedge reset) if (reset) begin
// Set each output to 0 by setting was_reset.
was_reset = 1'b1;
// Also we already prepare the counter reset for the next clock, as the clock already
// happened when this is "executed".
setvalue = 1'b1;
reset_val = 2'b00;
end else if (was_reset == 1'b1) begin
// The counter uses the same clock as this, so the reset is performed "now".
// We can now "reset the reset" and continue counting regularly.
was_reset = 1'b0;
setvalue = 1'b0;
reset_val = 2'b00;
end
assign fetch = ~was_reset && (mode == 2'b00);
assign decode = ~was_reset && (mode == 2'b01);
assign execute = ~was_reset && (mode == 2'b10);
assign writeback = ~was_reset && (mode == 2'b11);
endmodule

84
Decoder_TestBench.sv Normal file
View File

@ -0,0 +1,84 @@
`default_nettype none
module Decoder_TestBench;
var logic clock, reset;
tri fetch, decode, execute, writeback;
Decoder dec(
.clock(clock),
.reset(reset),
.fetch(fetch),
.decode(decode),
.execute(execute),
.writeback(writeback)
);
// synthesis translate_off
initial begin
$timeformat(-9, 2, " ns", 20);
$display("%0t Initial Reset", $time);
clock = 1'b0;
#20 reset = 1'b1;
#20 reset = 1'b0;
assert(fetch == 1'b0);
assert(decode == 1'b0);
assert(execute == 1'b0);
assert(writeback == 1'b0);
$display("%0t Fetch", $time);
#20 clock = 1'b1;
#20 clock = 1'b0;
assert(fetch == 1'b1);
assert(decode == 1'b0);
assert(execute == 1'b0);
assert(writeback == 1'b0);
$display("%0t Decode", $time);
#20 clock = 1'b1;
#20 clock = 1'b0;
assert(fetch == 1'b0);
assert(decode == 1'b1);
assert(execute == 1'b0);
assert(writeback == 1'b0);
$display("%0t Execute", $time);
#20 clock = 1'b1;
#20 clock = 1'b0;
assert(fetch == 1'b0);
assert(decode == 1'b0);
assert(execute == 1'b1);
assert(writeback == 1'b0);
$display("%0t Writeback", $time);
#20 clock = 1'b1;
#20 clock = 1'b0;
assert(fetch == 1'b0);
assert(decode == 1'b0);
assert(execute == 1'b0);
assert(writeback == 1'b1);
$display("%0t Fetch", $time);
#20 clock = 1'b1;
#20 clock = 1'b0;
assert(fetch == 1'b1);
assert(decode == 1'b0);
assert(execute == 1'b0);
assert(writeback == 1'b0);
$display("%0t Reset", $time);
clock = 1'b0;
#20 reset = 1'b1;
#20 reset = 1'b0;
assert(fetch == 1'b0);
assert(decode == 1'b0);
assert(execute == 1'b0);
assert(writeback == 1'b0);
$display("Success!");
end
// synthesis translate_on
endmodule