Implement CPU "cycle" decoder
This commit is contained in:
47
Decoder.sv
Normal file
47
Decoder.sv
Normal 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
84
Decoder_TestBench.sv
Normal 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
|
Reference in New Issue
Block a user