Programmable Devices
CPLDs, FPGAs, SoC FPGAs, Configuration, and Transceivers
20707 Discussions

Array Multiplying CPU

Altera_Forum
Honored Contributor II
1,022 Views

I coded the following as a CPU to multiply two arrays and I don't get the proper output. I do get some output but it's not correct. Any ideas are appreciated: 

--------------------------------------------------------------------------------------------- 

LIBRARY ieee; 

USE ieee.std_logic_1164.ALL; 

USE ieee.std_logic_arith.ALL; 

USE ieee.std_logic_signed.ALL; 

 

ENTITY cpu_test IS 

PORT (clk: IN std_logic; 

output: OUT std_logic_vector(7 downto 0)); 

END cpu_test; 

 

ARCHITECTURE rtl OF cpu_test IS 

SIGNAL north, west: std_logic_vector(3 downto 0); 

SIGNAL north_int, west_int: signed(3 downto 0); 

SIGNAL sum_int, stored_int: signed(7 downto 0); 

SIGNAL result_int: signed(7 downto 0); 

SIGNAL result: std_logic_vector(7 downto 0); 

SIGNAL stored: std_logic_vector(7 downto 0); 

 

TYPE matrix IS ARRAY (3 downto 0) OF std_logic_vector(3 downto 0); 

 

CONSTANT matrix_A: matrix :=((X"9",X"8",X"7",X"6")); 

 

CONSTANT matrix_B: matrix :=((X"5",X"4",X"3",X"2")); 

 

BEGIN 

PROCESS (clk) 

VARIABLE matrix_result: std_logic_vector(7 downto 0) := X"00"; 

VARIABLE addr: INTEGER RANGE 0 TO 4 := 0; 

BEGIN 

IF (addr < 4) THEN 

west <= matrix_A(addr); 

 

north <= matrix_B(addr); 

 

stored <= matrix_result; 

 

IF (clk'EVENT AND clk = '1') THEN 

north_int <= SIGNED(north); 

 

west_int <= SIGNED(west); 

 

sum_int <= north_int * west_int; 

 

stored_int <= SIGNED(stored); 

 

result_int <= stored_int + sum_int; 

 

result <= STD_LOGIC_VECTOR(result_int); 

END IF; 

 

matrix_result := result; 

 

output <= matrix_result; 

 

addr := addr + 1; 

END IF; 

END PROCESS; 

END rtl; 

--------------------------------------------------------------------- 

Something is wrong with the way I'm thinking about this design, but I'm not sure what.
0 Kudos
2 Replies
Altera_Forum
Honored Contributor II
284 Views

The code is based on several misunderstandings of VHDL (or programmable logic in general) operation principles, I think. I'm unable to see the intended function exactly, but I can tell what constructs can't work for sure: Basically, the addr variable is incremented in concurrent code, not triggered by a clock. That means, it has no defined value at all. As a result, all expressions depending on addr are removed by the compiler, cause no value can be calculated for them. 

 

If you wan't to perform calculations for an array, you have two options: 

1. You can perform it sequentially, incrementing addr in a clock synchronous process. 

2. You can perform it in parallel, using a FOR .. GENERATE or FOR.. LOOP construct. In this case, also the results must be assigned in parallel, e. g. to a result array. 

 

Apart from this issue, the assignments within your clock synchronous process part probably won't have the intended result (here I'm only guessing what's actually intended). Each assignment implies a delay of one clock cycle. E. g. when north_int is present one cycle after north, sum_int has already a delay of two cycles, result_int three cycles and result four cycles.
0 Kudos
Altera_Forum
Honored Contributor II
284 Views

I'm trying to create one CPU to be used as 16 components in a systolic array configuration for multiplying two 4x4 matrices. The arrays created in this code are just samples of the first row and first column of the matrices. 

 

The end result has to be a 16-cpu systolic array system that takes in two 4x4 arrays, one from the west a column per clock and one from the north a row per clock, and computes the resulting array. 

 

I understand now what you mean about the delaying in the if loop, I'm reading the references I have to try to learn what needs to be done correctly. No luck so far.
0 Kudos
Reply