0

I'm storing two tables in two signals. One table keeps the key (address) and the other keeps the value corresponding to the key. I need to compare an input to the key and, if they match, return the value stored.

The reason why I need this is for a dynamic lookup table for branch instruction prediction. In the fetch stage of a processor I get the input Instruction_Address and I return a branch_To_Address and a branch_Prediction. Initially I want to store 16 predictions/branch addresses and use a circular buffer ring to overwrite as needed.

I've been trying to use a FOR with a nested IF to search for the key inside keyTable.

The whole module seems to work fine, except when I compare two bit_vectors with the IF statement. I need this twice (one on read and another on write) and hence I need to "sweep" the keysTable so I can see if the address that is being looked up has an entry.

I noticed the error upon simulation, where the ELSE clause is being called always regardless of the keysTable having the right entries.

Verifiable example:

library IEEE;
use ieee.numeric_bit.all;

entity branch_prediction_table is
generic (
    addrSize    : NATURAL   := 4;
    tableSize   : NATURAL   := 4);
port (
    clock : in bit;
    input_addr: in bit_vector(addrSize-1 downto 0);
    return_value : out bit );
end branch_prediction_table;

architecture branch_table of branch_prediction_table is

    signal keysTable : bit_vector(addrSize*tableSize-1 downto 0) := ( others => '0');
    signal valuesTable : bit_vector(tableSize*2-1 downto 0) := ( others => '0');

begin

    tableProc: process(clock) is

        variable valueFromTable : bit;
    begin
        if rising_edge(clock) then

            search_table: for iR in (tableSize-1) to 0 loop

                if (keysTable(addrSize*(iR+1)-1 downto addrSize*iR) = input_addr) then
                    valueFromTable := valuesTable((iR+1)*2-1);
                    EXIT search_table;
                else
                    valueFromTable := '0';
                end if;

            end loop search_table;

            return_value <= valueFromTable;

        end if; -- rising_edge(clock)
    end process tableProc;
end branch_table;

with verifiable testbench simulation TCL:

add wave -position insertpoint  \
sim:/branch_prediction_table/addrSize \
sim:/branch_prediction_table/clock \
sim:/branch_prediction_table/input_addr \
sim:/branch_prediction_table/keysTable \
sim:/branch_prediction_table/return_value \
sim:/branch_prediction_table/tableSize \
sim:/branch_prediction_table/valuesTable
force -freeze sim:/branch_prediction_table/valuesTable 11111111 0
force -freeze sim:/branch_prediction_table/keysTable 1111101001100011 0
force -freeze sim:/branch_prediction_table/clock 0 0, 1 {5000 ps} -r {10 ns}
run 10 ns
force -freeze sim:/branch_prediction_table/input_addr 1010 0
run 20 ns
force -freeze sim:/branch_prediction_table/input_addr 1111 0
run 10 ns

and testbench simulation result showing that error is indeed in the IF: Verifiable Testbench Simulation

I have tried converting them with to_integer(unsigned(bit_vector1)) = to_integer(unsigned(bit_vector2)) with no avail

Pedro
  • 74
  • 1
  • 11
  • There is no `else` in the code you've shown. – mkrieger1 Nov 09 '19 at 20:26
  • @mkrieger1 there we go – Pedro Nov 09 '19 at 20:30
  • What are the specific values of `keysTable(addrSize*(iR+1)-1 downto addrSize*iR)` and `input_addr` which you think would compare equal, but don't? – mkrieger1 Nov 09 '19 at 20:32
  • Or - how do you come to the conclusion that the `else` branch is taken? Maybe `valuesTable((iR+1)*2-1)` is `'0'`? – mkrieger1 Nov 09 '19 at 20:35
  • Given `signal valuesTable : bit_vector(tableSize*2-1 downto 0) := ( others => '0');`, that seems likely. – mkrieger1 Nov 09 '19 at 20:36
  • Sorry, I'm not going to read that. Please construct a minimal example that demonstrates the problem. – mkrieger1 Nov 09 '19 at 20:44
  • You're code is still not a [mcve] and TCL stimulus isn't universally supported. There's a [tag:modelsim] tag, a wider plenum of potential answerers might benefit from an actual testbench. Validate the contents of the two tables (or initialize them in VHDL). Using an array with composite elements may be easier to index correctly (`type key_table is array 0 to 2 ** TBLSZ - 1 of bit_vector (ADSZ - 1 downto 0); signal keystable: key_table;` where `for in 0 to TBLSZ - 1 loop if keystable(i) = input_addr then` ...). –  Nov 10 '19 at 03:14
  • 2
    `for iR in (tableSize-1) to 0 loop` (IEEE Std 1076-2008 5.2 Scalar types, "A range specifies a subset of values of a scalar type. A range is said to be a null range if the specified subset is empty. The range L to R is called an ascending range; if L > R, then the range is a null range. The range L downto R is called a descending range; if L < R, then the range is a null range."). 10.10 Loop statement "For the execution of a loop with a for iteration scheme, the discrete range is first evaluated. If the discrete range is a null range, the iteration scheme is said to be complete, ..." –  Nov 10 '19 at 06:29
  • While this error is typographic there may be further errors. –  Nov 10 '19 at 06:30
  • @user1155120 please add your comment as an answer so I can accept it :) VHDL isn't a language that I use very often and forgot (or didn't think) that in FOR loops it needed to be `downto` [Working Simulation Results](https://i.stack.imgur.com/TCuHF.png) – Pedro Nov 10 '19 at 12:53
  • Duplicate of [VHDL “For” Loop Null Range](https://stackoverflow.com/questions/36499014/vhdl-for-loop-null-range). –  Nov 11 '19 at 02:13

1 Answers1

0

As user1155120 pointed out:

The problem lies within search_table: for iR **in** (tableSize-1) to 0 loop

It should've been "down to" as L > R. Since I used "in" with L>R, that produces a null range and the for loop iteration is said to be complete.

(IEEE Std 1076-2008 5.2 Scalar types, "A range specifies a subset of values of a scalar type. A range is said to be a null range if the specified subset is empty. The range L to R is called an ascending range; if L > R, then the range is a null range. The range L downto R is called a descending range; if L < R, then the range is a null range.").

10.10 Loop statement "For the execution of a loop with a for iteration scheme, the discrete range is first evaluated. If the discrete range is a null range, the iteration scheme is said to be complete, ..."

Community
  • 1
  • 1
Pedro
  • 74
  • 1
  • 11