0
\$\begingroup\$

I've been learning VHDL for five days and I've got stuck. Currently I'm trying to implement a combinatorial cross-point switch between Port A (input 8-bit) and Port B (output 8-bit), depending on what's selected on the input port named "Sel" (7-bit).

Consider this (shortened) truth table:

Sel          B[7]    B[6]    B[5]    B[4]    B[3]    B[2]    B[1]    B[0]
0   0000000   1       1       1       1       1       1       1      A[0]
1   0000001   1       1       1       1       1       1       1      A[1]
2   0000010   1       1       1       1       1       1       1      A[2]
3   0000011   1       1       1       1       1       1       1      A[3]
4   0000100   1       1       1       1       1       1       1      A[4]
5   0000101   1       1       1       1       1       1       1      A[5]
6   0000110   1       1       1       1       1       1       1      A[6]
7   0000111   1       1       1       1       1       1       1      A[7]
8   0001000   1       1       1       1       1       1      A[0]    1
9   0001001   1       1       1       1       1       1      A[1]    1
10  0001010   1       1       1       1       1       1      A[2]    1
11  0001011   1       1       1       1       1       1      A[3]    1
12  0001100   1       1       1       1       1       1      A[4]    1
13  0001101   1       1       1       1       1       1      A[5]    1
14  0001110   1       1       1       1       1       1      A[6]    1
15  0001111   1       1       1       1       1       1      A[7]    1
...

If "Sel" is 9, this means A[1] and B[1] should be connected to each other. Anything that happens on A[1] should be reflected on B[1]. All other pins on B should be "1".

What I've come up with so far is a case-block, like this:

 case sel is
     when "0000000"   => PB <= "1111111" & PA(0);
     when "0000001"   => PB <= "1111111" & PA(1);
     when "0000010"   => PB <= "1111111" & PA(2);
     when "0000011"   => PB <= "1111111" & PA(3);
     when "0000100"   => PB <= "1111111" & PA(4);
     when "0000101"   => PB <= "1111111" & PA(5);
     when "0000110"   => PB <= "1111111" & PA(6);
     when "0000111"   => PB <= "1111111" & PA(7);
     when "0001000"   => PB <=  "111111" & PA(0) & '1';
     ...
 end case;

Which does what I want, but it's horrible because if I need to change something in the logic later on I will have to rewrite all the whens.

While peeking the truth table I saw a pattern. The three low bits of "Sel" equals the bit-number in Port A, while the four high bits equals the pin number in Port B.

Question: Is there some way to use this information to recreate the whole look up-table using a for-loop (or similiar), to replace my dinosaur case-block?

\$\endgroup\$
4
\$\begingroup\$

Disclaimer: I normally use Verilog so please follow the principle of what I write, not the exact syntax.

An important part of programming is to analyse your data before you do anything.

In this case you should observe that 3 LS bits select which A(..) you take so the first improvement is to use

A( sel(2 downto 0) )

Next I have small problem because that leaves 4 select bits which is 16 combinations but you have only 8 B(...). So for now I'll ignore the MS sel bit.

The second optimisation is that you can now use select bits 5..3 to determine which B you want. But before that you give it a default value:

PB <= (others '1' );
PB( sel(5 downto 3) ) <=  A( sel(2 downto 0) );

But that means you do two assignment to the same variable and that only is allowed if you do it in the same process.

Last but not least is to convert the above code so that the types are all correct. I always struggle with that in VHDL so that would require about an hour of my time. I leave that to you.

\$\endgroup\$
  • \$\begingroup\$ PB(to_integer(unsigned(sel(5 downto 3)))) <= PA(to_integer(unsigned(sel(2 downto 0)))); where the expressions determining the indexes of PB are derived by converting 3 'bit' sel slices to unsigned (numerical unsigned binary) then to integer, the base type of the std_logic_vector index. \$\endgroup\$ – user8352 Oct 7 '19 at 6:36
  • \$\begingroup\$ @user8352 Thank you. It is also an example why personally find VHDL difficult to read. To me the expression above distracts from the quintessence of the code, and the above is just a simple set of type conversions. \$\endgroup\$ – Oldfart Oct 7 '19 at 6:40
  • \$\begingroup\$ @Oldfart you wouldn't need all that if the select signal had the appropriate numeric type. \$\endgroup\$ – scary_jeff Oct 7 '19 at 12:10
1
\$\begingroup\$

The three LSBs control which bit of A is used, and the three MSBs control which bit of B is driven. So you just need an 8:1 multiplexer followed by a 1:8 decoder. With this hint, do I need to write out the code for you?

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.