Question

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
Was it helpful?

Solution

When you write (below) the Right hand side is an Integer (Decimal, base10), not binary (base2). Only use non-blocking when implying flip-flops.

initial begin
  RW <=     0;
  MD <=    00;
  BS <=    00;
  PS <=     0;
  MW <=     0;
  FS <= 00000;
  MB <=     0;
  MA <=     0;
  CS <=     0;
end

What you want is:

initial begin
  RW = 'b0    ;
  MD = 'b00   ;
  BS = 'b00   ;
  PS = 'b0    ;
  MW = 'b0    ;
  FS = 'b00000;
  MB = 'b0    ;
  MA = 'b0    ;
  CS = 'b0    ;
end

NB: You do not need to to include leading 0's although it can help readability.

To add to Will's comment, It is recommended to size your numbers (5'b10110 instead of 'b10110), I do however tend to leave reset or initial conditions un-sized to minimise the refactoring required for code changes.

Other available options for number bases in verilog are:

'b0 // Binary      (base2)
'o0 // Octal       (base8)
'd0 // Decimal     (base10)
'h0 // Hexadecimal (base16)
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top