2
votes

I'm a beginner at vhdl and I'm trying to make a 8 bit divider using shift and subtract method. The code for the divider is okay, I guess, but I'm having problems in simulating the inputs. When I use the Verilog test fixture, my inputs which should be (dividend=51 [00110011b], divisor=19 [00010011b]) always end up becoming (dividend=49 [00110001b], divisor=49 [00110001b])) in iSim, and then the outputs (Quotient and remainder = xxxxxxx (unknown)) instead of (quotient=2[00000010b] and remainder=13 [00001101b])... As I mentioned before, I'm a beginner at vhdl and I've been at this for five hours, I've tried my best to search for a solution online, but failed.... so any help or alternative solution would be greatly appreciated. I'm using Xilinx ISE 14.3 and iSim.

Here is the code for the 8 bit binary divider.

library IEEE; 
use IEEE.STD_LOGIC_1164.all; 
use IEEE.STD_LOGIC_UNSIGNED.all;  
use IEEE.STD_LOGIC_ARITH.all; 

entity division is  
    generic(SIZE: INTEGER := 8); 
    port(reset: in STD_LOGIC;                           --reset
        en: in STD_LOGIC;                               --enable
        clk: in STD_LOGIC;                              --clock

        num: in STD_LOGIC_VECTOR((SIZE - 1) downto 0);  --dividend
        den: in STD_LOGIC_VECTOR((SIZE - 1) downto 0);  --divisor
        res: out STD_LOGIC_VECTOR((SIZE - 1) downto 0); --result/quotient
        rm: out STD_LOGIC_VECTOR((SIZE - 1) downto 0)   --remainder
        ); 
end division; 

architecture behav of division is 
    signal bufreg: STD_LOGIC_VECTOR((2 * SIZE - 1) downto 0); --signal array to hold both accumulator and dividend registers as one i.e bufreg(18 bits)
    signal dbuf: STD_LOGIC_VECTOR((SIZE - 1) downto 0);       --signal array to hold the divisor
    signal count: INTEGER range 0 to SIZE;                    --count to determine when to stop

    alias ADreg is bufreg((2 * SIZE - 1) downto SIZE);        --ADreg is is alias for top half of bufreg register(17th to 9th bit) 
    alias DVNDreg is bufreg((SIZE - 1) downto 0);             --DVNDreg is is alias for bottom half of bufreg register(8th to 0th bit)
begin 
--our process begins here
    p_001: process(reset, en, clk) 
    begin 
        if reset = '1' then 
            res <= (others => '0'); 
            rm <= (others => '0'); 
            count <= 0; 
        elsif rising_edge(clk) then 
            if en = '1' then 
                case count is 
                when 0 => 
                    ADreg <= (others => '0'); 
                    DVNDreg <= num; 
                    dbuf <= den; 
                    res <= DVNDreg; 
                    rm <= ADreg; 
                    count <= count + 1; 
                when others => 
                    if bufreg((2 * SIZE - 2) downto (SIZE - 1)) >= dbuf then 
                        ADreg <= '0' & (bufreg((2 * SIZE - 3) downto (SIZE - 1)) - dbuf((SIZE - 2) downto 0)); 
                        DVNDreg <= DVNDreg ((SIZE - 2) downto 0) & '1'; 
                    else 
                        bufreg <= bufreg((2 * SIZE - 2) downto 0) & '0'; 
                    end if; 
                    if count /= SIZE then 
                        count <= count + 1; 
                    else 
                        count <= 0; 
                    end if; 
                end case; 
            end if; 
        end if; 
    end process; 
end behav;

And here is the code for the Verilog test fixture (.v file):

module BINdivisionTEST;

    // Inputs
    reg reset;
    reg en;
    reg clk;
    reg [7:0] num ;
    reg [7:0] den ;

    // Outputs
    wire [7:0] res;
    wire [7:0] rm;

    // Instantiate the Unit Under Test (UUT)
    division uut (
        .reset(reset), 
        .en(en), 
        .clk(clk), 
        .num(num), 
        .den(den), 
        .res(res), 
        .rm(rm)
    );

    initial begin
        // Initialize Inputs
        reset = 0;
        en = 0;
        clk = 0;
        //num = 0;
        //den = 0;

        // Wait 100 ns for global reset to finish
        #100;
        en = 1;
        #100;   
      clk=1;        
        num <= "00110011" ;
      den <= "00010011" ;
        // Add stimulus here

    end

endmodule

My biggest problems seem to be initialization of the inputs and probably some mistaken assignments, misuse of the test fixture file and some bad coding. I should also add that the divider code was compiled in vhdl, ISE 14.3. I'm extremely sorry if this has been answered before and I don't mean to piss anyone off by uploading bad and amateur code. If this kind of problem has been addressed before could you please provide me with a link. Again, any help is greatly appreciated.

2

2 Answers

2
votes

The simulator may be treating those as strings instead of numbers. Try changing:

num <= "00110011" ;
den <= "00010011" ;

to:

num <= 8'b00110011;
den <= 8'b00010011;
1
votes

I'm no expert on Verilog but it looks as if you might not be asserting Reset to your VHDL component before testing it.

That would lead "Count" in an uninitialised state so that when you use it, anything could happen and the "XXXX" outputs are a reflection of that.

The reset sequence should look like

En <= '0';
Clk <= '0';
Reset <= '1';
wait for 100 ns;
Reset <= '0';
wait for 100 ns;
-- start testing here

(in VHDL of course ... but it'll translate to Verilog easily)