diff --git a/Decoder.sv b/Decoder.sv new file mode 100644 index 0000000..9ba458c --- /dev/null +++ b/Decoder.sv @@ -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 \ No newline at end of file diff --git a/Decoder_TestBench.sv b/Decoder_TestBench.sv new file mode 100644 index 0000000..3a69b0f --- /dev/null +++ b/Decoder_TestBench.sv @@ -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 \ No newline at end of file