I'm trying to create an instruction decoder in Verilog using Xilinx. My apologies for not having the cleanest code, I'm still learning Verilog. The issue I am having is that my FS result is incorrect.
I expect to see 00010 but instead I see 01010. As I debug, I changed the FS non-blocking assignment for ADD from 00010 to 01010 just to see what the result would be and I end up with FS being 10010. This leads me to believe that the bit[3] of FS is adding an extra 1 somehow. This is my verilog code:
`timescale 1ns / 1ps
`include "OPCODES.vh"
module instructiondecoder(
input [31:0] instruction,
//Control Word Values
output reg RW,
output reg [1:0] MD,
output reg [1:0] BS,
output reg PS,
output reg MW,
output reg [4:0] FS,
output reg MB,
output reg MA,
output reg CS,
output [4:0] AA,
output [4:0] BA
);
assign AA = instruction[19:15];
assign BA = instruction[14:10];
initial begin
RW <= 0;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 00000;
MB <= 0;
MA <= 0;
CS <= 0;
end
always @ (instruction)
begin
case(instruction[31:25])
`NOP:
begin
RW <= 0;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 00000;
MB <= 0;
MA <= 0;
CS <= 0;
end
`ADD:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 00010;
MB <= 0;
MA <= 0;
CS <= 0;
end
`SUB:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 00101;
MB <= 0;
MA <= 0;
CS <= 0;
end
`SLT:
begin
RW <= 1;
MD <= 10;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 00101;
MB <= 0;
MA <= 0;
CS <= 0;
end
`AND:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 01000;
MB <= 0;
MA <= 0;
CS <= 0;
end
`OR:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 01010;
MB <= 0;
MA <= 0;
CS <= 0;
end
`XOR:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 01100;
MB <= 0;
MA <= 0;
CS <= 0;
end
`ST:
begin
RW <= 0;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 1;
FS <= 00000;
MB <= 0;
MA <= 0;
CS <= 0;
end
`LD:
begin
RW <= 1;
MD <= 01;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 00000;
MB <= 0;
MA <= 0;
CS <= 0;
end
`ADI:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 00010;
MB <= 1;
MA <= 0;
CS <= 1;
end
`SBI:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 00101;
MB <= 1;
MA <= 0;
CS <= 1;
end
`NOT:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 01110;
MB <= 0;
MA <= 0;
CS <= 0;
end
`ANI:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 01000;
MB <= 1;
MA <= 0;
CS <= 0;
end
`ORI:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 01010;
MB <= 1;
MA <= 0;
CS <= 0;
end
`XRI:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 01100;
MB <= 1;
MA <= 0;
CS <= 0;
end
`AIU:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 00010;
MB <= 1;
MA <= 0;
CS <= 0;
end
`SIU:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 00101;
MB <= 1;
MA <= 0;
CS <= 0;
end
`MOV:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 00000;
MB <= 0;
MA <= 0;
CS <= 0;
end
`LSL:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 10100;
MB <= 0;
MA <= 0;
CS <= 0;
end
`LSR:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 11000;
MB <= 0;
MA <= 0;
CS <= 0;
end
`JMR:
begin
RW <= 1;
MD <= 00;
BS <= 00;
PS <= 0;
MW <= 0;
FS <= 11000;
MB <= 0;
MA <= 0;
CS <= 0;
end
`BZ:
begin
RW <= 0;
MD <= 00;
BS <= 01;
PS <= 0;
MW <= 0;
FS <= 00000;
MB <= 1;
MA <= 0;
CS <= 1;
end
`BNZ:
begin
RW <= 0;
MD <= 00;
BS <= 01;
PS <= 1;
MW <= 0;
FS <= 00000;
MB <= 1;
MA <= 0;
CS <= 1;
end
`JMP:
begin
RW <= 0;
MD <= 00;
BS <= 11;
PS <= 0;
MW <= 0;
FS <= 00000;
MB <= 1;
MA <= 0;
CS <= 1;
end
`JML:
begin
RW <= 1;
MD <= 00;
BS <= 11;
PS <= 0;
MW <= 0;
FS <= 00111;
MB <= 1;
MA <= 1;
CS <= 1;
end
default :
begin
RW <= 1'bx;
MD <= 2'bxx;
BS <= 2'bxx;
PS <= 1'bx;
MW <= 1'bx;
FS <= 5'bxxxxx;
MB <= 1'bx;
MA <= 1'bx;
CS <= 1'bx;
end
endcase
end
endmodule
The following is my OPCODES include:
`ifndef OP_CODES
`define OP_CODES
`define NOP 7'b0000000
`define ADD 7'b0000010
`define SUB 7'b0000101
`define SLT 7'b1100010
`define AND 7'b0001000
`define OR 7'b0001010
`define XOR 7'b0001100
`define ST 7'b0000001
`define LD 7'b0100001
`define ADI 7'b0100010
`define SBI 7'b0100101
`define NOT 7'b0101110
`define ANI 7'b0101000
`define ORI 7'b0101010
`define XRI 7'b0101100
`define AIU 7'b1100010
`define SIU 7'b1000101
`define MOV 7'b1000000
`define LSL 7'b0110000
`define LSR 7'b0110001
`define JMR 7'b1100001
`define BZ 7'b0100000
`define BNZ 7'b1100000
`define JMP 7'b1000100
`define JML 7'b0000111
`endif
And in this is my test:
`timescale 1ns / 1ps
`include "OPCODES.vh"
module instructionDecoder_test;
// Inputs
reg [31:0] instruction;
// Outputs
wire RW;
wire [1:0] MD;
wire [1:0] BS;
wire PS;
wire MW;
wire [4:0] FS;
wire MA;
wire MB;
wire CS;
wire [4:0] AA;
wire [4:0] BA;
// Instantiate the Unit Under Test (UUT)
instructiondecoder uut (
.instruction(instruction),
.RW(RW),
.MD(MD),
.BS(BS),
.PS(PS),
.MW(MW),
.FS(FS),
.MA(MA),
.MB(MB),
.CS(CS),
.AA(AA),
.BA(BA)
);
initial begin
// Initialize Inputs
// Wait 100 ns for global reset to finish
#100;
instruction = {`ADD, 5'd8, 5'd3, 5'd5, 10'b0}; //ADD
end
endmodule