Adaptation SystemC en VHDL

Adaptation SystemC en VHDL - Divers - Programmation

Marsh Posté le 08-03-2012 à 13:36:13    

Bonjour,
 
Dans le cadre d'un projet, je dois adapter un code en SystemC donné en VHDL. Ce code permet de résoudre un Sudoku. Le code fait appel à de la récursion qui n'est pas synthétisable du coup faut transformer en faisant des boucles le code de façon à enlever toutes traces de récursivité. Le problème c'est que j'y arrive pas :cry:  
J'ai essayé plein de trucs mais à chaque fois j'ai des résultats étranges (genre la grille est remplie qu'avec des 5 des 6 et des 8...). Voilà la fonction :  

Code :
  1. /// solves the puzzle with bruteforce. called recursively
  2. void solve_bruteforce(size_t r, size_t c)
  3. {
  4.  //puzzle already solved
  5.  if( this->done )
  6.   return;
  7.  // matrix completely filled. The puzzle is solved
  8.  if( r==this->n )
  9.  {
  10.   this->done=true;
  11.   return;
  12.  }
  13. debug_out(r,c);
  14.  //Move to the next row
  15.  if( c==this->n )
  16.  {
  17.   this->solve_bruteforce(r+1,0);
  18.  }
  19.  else if( this->array[r][c]==0 )
  20.  { //Empty position
  21.   size_t i;
  22.   for(i=1; i<=this->n; ++i)
  23.   {
  24.    //We have already used this number in this row/column/square
  25.    if( is_set( row_mask[r], i) ||
  26.     is_set( col_mask[c], i) ||
  27.     is_set( sqr_mask[c/this->b + this->b*(r/this->b)], i) )
  28.     continue;
  29.    do_set(row_mask[r], i);
  30.    do_set(col_mask[c], i);
  31.    do_set(sqr_mask[c/this->b + this->b*(r/this->b)], i);
  32.    this->array[r][c]=i;
  33.    this->solve_bruteforce(r,c+1);
  34.    if( this->done )
  35.     return;
  36.    this->array[r][c]=0;
  37.    do_unset(row_mask[r], i);
  38.    do_unset(col_mask[c], i);
  39.    do_unset(sqr_mask[c/this->b + this->b*(r/this->b)], i);
  40.   }
  41.  }
  42.  else
  43.  { //Position already filled
  44.   this->solve_bruteforce(r,c+1);
  45.  }
  46. }


 
Les fonctions is_set, do_set et do_unset sont des fonctions qui permettent respectivement de savoir si un bit est à 1, de le mettre à 1 et de le mettre à 0. b est la longueur d'un petit carré.
Ca serait cool de me dire comment je dois faire ou du moins comment je dois m'y prendre...  
 
Merci d'avance.

Reply

Marsh Posté le 08-03-2012 à 13:36:13   

Reply

Marsh Posté le 08-03-2012 à 13:40:26    

Quelle expérience as-tu avec VHDL?

 

La description fonctionnelle est très mal adaptée à une implémentation hadware.

 

Dans ce cas je génèrerai deux blocs séquencés, un générant une solution, l'autre vérifiant la solution. Ces blocs accédant à une SRAM (un tableau sera très certainement implémenté en SRAM si chaque accès est correctement séquencé)

 

En tous les cas ce n'est pas évident à faire...


Message édité par h3bus le 08-03-2012 à 13:41:02

---------------
sheep++
Reply

Marsh Posté le 09-03-2012 à 12:39:16    

Salut, merci pour la réponse rapide.
En fait là est le problème, j'ai été parachuté dans une FAC allemande où les mecs font du VHDL depuis 5 ans ou plus alors que moi que depuis l'an passé... (différence de système de formation des ingénieurs...). Du coup je me retrouve avec ce projet à faire et je suis paumé.
Le truc le plus dur que j'ai réussi à faire en VHDL c'est une FIFO.

Reply

Marsh Posté le 09-03-2012 à 12:53:20    

Pour l'instant le problème n'est pas le VHDL mais la représentation hardware du circuit et les machines d'état à réaliser.

 

Je te conseille de décomposer ton algorithme en machines d'état, puis de coucher sur une feuilles des modules simples hardware qui s'interfacent avec tes machines d'état.

 

C'est une gymnastique complètement différente de la programmation itérative.

 

Essaie d'oublier le concept de variable pour voir ça comme des registres, les boucles doivent être implémentées avec des machine d'état et des compteurs.
Pour le tableau représentant le sodoku, tu peux voir ça comme une zone mémoire qui n'a qu'une interface d'écriture et une de lecture.

 

ça ne t'aide pas beaucoup, je sais, essaie de ne traiter qu'une partie du problème pour commencer.

 

Je vais essayer d'y réfléchir de mon côté mais je ne te donnerai pas la solution, d'abord parce que je ne connais pas la technique et peut me planter, et aussi par ce que c'est contraire aux règle du forum.

 

Bon courage, n'hésite pas à poster ton avancement même si tu penses que c'est naze, on pourra te réorienter si tu ne sembles pas être dans la bonne voie!


Message édité par h3bus le 09-03-2012 à 12:54:19

---------------
sheep++
Reply

Marsh Posté le 15-03-2012 à 08:04:20    

Ok, merci
 
Il faut quand même qui je signale que le bout de code que j'ai présenté n'est qu'un petit morceau de ce qu'on nous a donné. Cette fonction est également accompagné d'une machine d'états.
 
En gros voilà comment ça fonctionne. La machine est composée de 4 états : WAITING, READING, WORKING et WRITING.
Dans le WAITING sont faîtes toutes les inits, si l'ordre donné n'est pas trop grand ou pas trop petit on passe au READING.
Au READING, si les données d'entrées sont trop grandes on les met à 0, si tous les "is_set" sont à 1 dans ce cas là on retourne au WAITING sinon on remplit la grille (avec les do_set). Tout cela ce fait avec des compteurs sur les lignes et les colonnes. Si le compteurs des lignes est à n (nombre total de ligne) on passe au WORKING.
Le WORKING lance l'algorithme que je dois adapter, tout simplement. Et on passe automatiquement au WRITING.
Au WRITING on écrit le tout en mémoire.
 
La plateforme de test étant déjà disponible pour le code en SystemC, je bosse directement sur le code source en essayant de remplacer les appels récursifs par des boucles. A chaque que je teste, ça marche pas du tout : Soit la grille bouge pas, soit c'est la grille de base sans les 9, soit y'a que des 5 des 8 et des 9... Bref un chouïa énervant.

Reply

Marsh Posté le 15-03-2012 à 13:03:08    

Vu l'algo tu ne pourras surement pas te passer des appels récursifs.
Bien sûr il ne faut pas les utiliser tel quels, mais les implémenter avec une pile (une LIFO, t'as fait une FIFO c'est presque le même chose).
 
La machine d'état principale que tu décrit ne pose pas de soucis, tu dois juste l'interfacer avec la machine d'état de résolution.


---------------
sheep++
Reply

Marsh Posté le 22-03-2012 à 07:38:17    

Suite à ce que tu m'as dit, j'ai fait une machine d'états de l'algo, dis-moi ce que t'en penses :  
http://img15.hostingpics.net/thumbs/mini_613814FSMVLSI.jpg
 
L'état IDLE, rien à dire^^
EMPTY_CASE c'est la où on cherche les cases vides, typiquement la condition if(array[r][c] == 0), si oui état suivant, si non soit c'est que tout est fini soit on incrémente les colonnes (je sais pas encore exactement comment je vais faire pour ça)
FILL on remplit la case (do_set...),  
TEST on regarde si y'a un conflit, si oui on remet le 0 (do_unset) et on revient. Et dès qu'il n'y a plus conflit ni 0, valid passe à 1 et on ajoute un étage à la pile.
SOLVE c'est juste un état ou un flag passe à 1 pour dire que c'est résolu.
Je vois bien qu'il faut utiliser la LIFO mais je sais pas concrètement comment : Tu vois en C, c'est facile mais là je vois pas trop comment on fait pour en utiliser à l'intérieur d'une machine d'états.  

Reply

Marsh Posté le 23-03-2012 à 01:15:28    

Les choses commencent à se poser.

 

Une petite remarque avant de passer à la LIFO, l'état TEST est complexe, il nécessite à lui seul un parcours du tableau pour vérifier la validité des valeurs en place. Cela dit je te conseille de mettre ça de côté, je vois plusieurs implémentation pour cette fonction, plus ou moins compliquées et rapides.

 

Concernant la LIFO, je perçois son utilisation ainsi:
- Dans l'état FILL on met dans la LIFO la case qu'on a remplie (r et c) et la valeur de la case
- Dans l'état TEST, si on détecte que le tableau est faux, on dépile la dernière valeurs mise dans la LIFO et:
   . Si la valeur est 9 (en gros on a tout essayé de 0 à 9) on fait un unset puis on dépile la valeur suivante et ainsi de suite jusqu'à avoir trouvé une case < 9. ensuite on passe à FILL qui va y incrémenter la case
   . Si la valeur est < 9 on passe à FILL qui va y incrémenter la case

 

Par ce procédé on implémente mode de fonctionnement récursif, avec des machines d'état et une lifo

 

Du coup il faudrait un autre état après test, disons UNSET pour réaliser cet algorithme.

 

Un petit détail, 0 ne représente pas une case vide (car 0 est une valeur possible d'une case). Il faut donc une valeur qui représente une case vide, 10 par exemple...

 

Voilà, je reviens de soirée un petit peu arrosée, excuse l'éventuel manque de clarté de mes propos ;)


Message édité par h3bus le 23-03-2012 à 01:21:06

---------------
sheep++
Reply

Marsh Posté le 24-03-2012 à 15:36:20    

Bon, en fait 0 représente bel et bien une case vide puisque sinon on aurait 10 valeurs différentes (de 0 à 9) à remplir dans 9 cases  ;)  (ça devait être du fait de l' "arrosage" )
 
Je me suis donc lancé dans un premier essai de description VHDL, ça doit être horrible syntaxiquement mais bon... Je vais mettre aussi le code de la pile, on sait jamais.
 

Code :
  1. library IEEE;
  2. use IEEE.std_logic_1164.all;
  3. use IEEE.numeric_std.all;
  4.  
  5.  
  6. entity brute_force is
  7.    port (
  8.    a_reset_l       : in  std_logic;
  9.    clk             : in  std_logic;
  10.    start_h         : in  std_logic;
  11.    order           : in  std_logic_vector( 3 downto 0);
  12.    data_o          : out std_logic_vector( 7 downto 0);
  13.    );
  14. end entity brute_force;
  15.  
  16. architecture rtl_vhdl of brute_force is
  17.  
  18. --Functions The sames functions which are made in the systemc file(Masking)
  19.  
  20. function is_set(mask:integer; pos:integer) return std_logic_vector is--With this function I can know if a bit is '1'
  21.    variable mk:std_logic_vector((TO_INTEGER(UNSIGNED(order))-1) downto 0);
  22.    variable temp1: std_logic_vector ((TO_INTEGER(UNSIGNED(order))-1) downto 0);
  23.    variable temp2: UNSIGNED ((TO_INTEGER(UNSIGNED(order))-1) downto 0);
  24.   begin  
  25.  
  26.    temp1:=std_logic_vector(TO_UNSIGNED(mask,(TO_INTEGER(UNSIGNED(order)))));--I convert a integer '1' into a vector of 49 bits
  27.    temp2:=(TO_UNSIGNED(1,(TO_INTEGER(UNSIGNED(order)))));--convert the value of mask into a vector of 49 bits
  28.  
  29.    mk:= temp1 and std_logic_vector(temp2 rol pos);
  30.    return mk;
  31. end is_set;
  32.  
  33.  
  34. function do_set(mask: integer; pos: integer) return integer is--With this procedure I can set a bit in the position indicated by pos.
  35.    variable temp1: UNSIGNED ((TO_INTEGER(UNSIGNED(order))-1) downto 0);
  36.    variable mask1:integer;
  37.     begin
  38.         temp1:=(TO_UNSIGNED(mask,(TO_INTEGER(UNSIGNED(order)))));
  39.         mask1:=TO_INTEGER((temp1 or (temp1 rol pos)));
  40.    return mask1;
  41. end do_set;
  42.  
  43. function do_unset(mask: integer ;  pos: integer ) return integer is
  44.    variable temp2: UNSIGNED ((TO_INTEGER(UNSIGNED(order))-1) downto 0);
  45.    variable mask2:integer;
  46. begin
  47.    temp2:=(TO_UNSIGNED(mask,(TO_INTEGER(UNSIGNED(order)))));--With this function I clear set a bit in the position indicated by pos.
  48.    mask2:=TO_INTEGER((temp2 and (not(temp2 rol pos))));
  49.    return mask2;
  50. end do_unset;
  51.  
  52. component LIFO
  53.             
  54.          data_i   : in  std_logic_vector(7 downto 0);
  55.         data_o  : out std_logic_vector(7 downto 0);
  56.         Rd,Wr     : in  std_logic;            
  57.         Empty,Full: out std_logic;    
  58.         Clk       : in  std_logic
  59.          size           : in integer);
  60. end component;
  61.  
  62. type mask is array (integer range<> ) of integer;
  63. signal row_mask : mask(0 to (TO_INTEGER(UNSIGNED(order))-1));
  64. signal col_mask : mask(0 to (TO_INTEGER(UNSIGNED(order))-1));
  65. signal sqr_mask : mask(0 to (TO_INTEGER(UNSIGNED(order))-1));
  66.  
  67.  
  68. type State is (IDLE, EMPTY_CASE, FILL, TEST,UNSET, SOLVE)
  69.  
  70. signal b : integer;--number of blocks
  71. signal row :integer;
  72. signal col : integer;
  73. signal n : integer;--
  74. signal zero : std_logic_vector(48 downto 0) := (others=>'0');
  75. signal sqr_index : integer;
  76. type sudoku is array (integer range<> ) of integer;
  77. signal matrix_sudoku : sudoku(0 to 2400);
  78.  
  79. signal State: State;
  80. signal State: NextState;
  81. signal valid:std_logic;
  82. signal found:std_logic;
  83. signal conflict:std_logic;
  84. signal allFilled:std_logic;
  85. signal start:std_logic;
  86. signal LIFO_out:std_logic_vector(7 downto 0);
  87. signal i:integer := '0';
  88. signal LIFO_FULL:std_logic;
  89. signal LIFO_EMPTY:std_logic;
  90.  
  91. begin
  92.    process(clk, a_reset_l)
  93.    begin
  94.        if (a_reset_l = '0') then
  95.            state <= waiting;
  96.        elsif (clk'event and clk='1') then
  97.            state <= next_state;
  98.        end if;
  99.    end process;
  100.  
  101.    process(State, NextState, start, found, col, row, valid, conflict, LIFO_out, allFiled)
  102.  
  103.     b <= TO_INTEGER(UNSIGNED(order));
  104.     n <= b*b;
  105.     col <= '0';
  106.     row <= '0';
  107.    begin
  108.        case state is
  109.            when IDLE =>
  110.                if(start/= '0') then NextState <= EMPTY_CASE;
  111.                else NextState <= IDLE;
  112.                end if;
  113.          
  114.            when EMPTY_CASE =>
  115.                 
  116.                if(matrix_sudoku(row*b + col) = 0) then
  117.                    found <= '1';
  118.                 else col <= col + '1';
  119.                 end if;
  120.                 
  121.                if(found = '1') then NextState <= FILL;
  122.                elsif(col = n) then row <= row + '1';
  123.                                    col <= '0';
  124.                elsif(row = n or LIFO_FULL = '1') then allFiled <= '1';
  125.                                    NextState <= SOLVE;
  126.                end if;
  127.                 
  128.          
  129.            when FILL =>
  130.                 i <= i + '1';
  131.                 if( i < n)
  132.                     if((is_set(row_mask(row),i) or is_set(col_mask(col),i) or
  133.                     is_set(sqr_mask(sqr_index),i)) \= zero) then valid <= '1';
  134.                     else conflict <= '1';
  135.                     end if;
  136.                 
  137.                     row_mask(row)<= do_set(row_mask(row),i);
  138.                     col_mask(col)<=do_set(col_mask(col),i);
  139.                     sqr_mask(sqr_index)<=do_set(sqr_mask(sqr_index),i);
  140.                     matrix_sudoku(row*b + col)<= i;
  141.                     LIFO port map(data_i => matrix_sudoku(row*b + col), data_o =>LIFO_out,
  142.                                 Full => LIFO_FULL, Empty =>LIFO_EMPTY,
  143.                                 Rd => '0', Wr => '1', Clk => clk, size => n);
  144.                     if(col < n) then col <= col + '1';
  145.                     end if;
  146.                     if(valid = '1' and LIFO_FULL = '1') then NextState <= EMPTY_CASE;
  147.                     elsif(conflict = '1') then NextState <= TEST;  
  148.                     end if;
  149.                 else NextState <= SOLVE;
  150.                 end if;
  151.          
  152.            when TEST =>
  153.                 LIFO port map(data_i => matrix_sudoku(row*b + col), data_o =>LIFO_out,
  154.                                 Full => LIFO_FULL, Empty =>LIFO_EMPTY,
  155.                                 Rd => '0', Wr => '1', Clk => clk, size => n);
  156.                 if( TO_INTEGER(UNSIGNED(LIFO_out) = n)) then NextState <= UNSET;
  157.                 else NextState <= FILL;
  158.                         valid <= '1';
  159.                 end if;
  160.                
  161.             when UNSET =>
  162.                matrix_sudoku(row*b + col)<= 0;
  163.                row_mask(row)<= do_unset(row_mask(row),i);
  164.                col_mask(col)<=do_unset(col_mask(col),i);
  165.                sqr_mask(sqr_index)<=do_unset(sqr_mask(sqr_index),i);
  166.                 NextState <= TEST;
  167.              
  168.            when SOLVE =>
  169.                NextState <= IDLE;
  170.          
  171.            when others =>
  172.                NextState<=IDLE;
  173.        end case;
  174.      
  175.    end process;
  176. end process;
  177. end architecture;


 
Evidemment comme cet un premier essai, je pense qu'il y a beaucoup d'erreur. Ca serait cool que tu me dises ce que t'en pense. Notamment sur l'utilisation de la pile comme composant (je savais pas comment faire autrement) ou la boucle for que j'ai enlevé et puis même sur les fonctions de masques je suis franchement pas sûr de moi au niveau de l'implémentation de ces fonctions.  
 

Code :
  1. entity lifo is
  2.  
  3.     port(data_i   : in  std_logic_vector(7 downto 0); -- input vector
  4.          data_o  : out std_logic_vector(7 downto 0); -- output vector
  5.          Rd,Wr     : in  std_logic;         -- read,write control signals     
  6.          Empty,Full: out std_logic;         -- condition signals
  7.          Clk       : in  std_logic
  8.   size     : in integer); 
  9. generic(n: NATURAL:= size*size);         -- LifO size
  10.   end lifo;
  11.   architecture behavioral of lifo is
  12.     TYPE    StorageT is array(0 to n-1) of std_logic_vector(15 downto 0);
  13.     signal  lifo: StorageT;           -- LifO memory
  14.     signal  last: integer range -1 to n-1;
  15.   begin
  16.     process (Clk)
  17.     begin
  18.       if (Clk = '1') AND (Wr = '1') then     -- write operation
  19.         if (last=n-1) then NULL;             -- lifo already full
  20.         else
  21.           if (last=n-2) then  Full  <= '1'; end if;
  22.           if (last=-1 ) then  Empty <= '0'; end if;
  23.           lifo(last+1) <= data_in;
  24.           last         <= last+1;
  25.         end if;
  26.       elsif (Clk = '1') AND (Rd = '1') then  -- read operation
  27.         if (last=-1) then NULL;             -- lifo already empty
  28.         else
  29.           data_out    <= lifo(last);
  30.           last <= last-1; Full <= '0';
  31.           if (last = -1) then Empty <= '1'; end if;
  32.         end if;
  33.       end if;
  34.     end process;
  35.   end behavioral;


 
Voilà le code de la pile, là je sais pas tellement quoi mettre au niveau de la taille de la pile. C'est dommage qu'il n'y ait pas de balise VHDL... J'espère que cela va être suffisamment lisible. Merci pour tout en tout cas et pour une fin de soirée je trouve tes propos relativement clairs  :)


Message édité par Gefroren le 28-03-2012 à 16:06:28
Reply

Marsh Posté le 25-03-2012 à 21:23:45    

Bon le code de la pile devrait synthétiser.
 
Pour le reste ça va pas passer!
 
Notamment tu ne peux pas instancier ta LIFO dans un process, il faut l'instancier dans l'architecture. La machine d'état gère ensuite les signaux d'interface.
 
Je pige pas des masses pourquoi tu n'as pas choisit un tableau à deux dimensions pour le sudoku.
 
En ce qui concerne la taille de la pile, en toute logique c'est le nombre de case de ton sudoku.
 
Pense à cadencer tes process sur une horloge.
 
Je vois pas mal d'erreur das le code, sans avoir regardé l'algorithmique. Tu pense encore trop itératif, n'oublie pas qu'à chaque coup d'horloge, tout le contenu du process est exécuté, et de manière parallèle.


---------------
sheep++
Reply

Marsh Posté le 25-03-2012 à 21:23:45   

Reply

Marsh Posté le 27-03-2012 à 08:21:41    

Ah ben si déjà la pile ça va, c'est déjà bien. Je savais que l'autre partie ne pouvais pas passer, c'était un premier essai.
 
Ok merci pour la LIFO, j'ai corrigé le problème.  
 
L'histoire du tableau à une dimension ne vient pas de moi. On nous a dit que les tableaux à deux dimensions n'étaient pas synthétisables et que du coup il  fallait changer celui pour le rendre 1D, voilà pourquoi.
 
La grosse machine d'états est cadencée par une horloge qui se trouve ligne 91, je suppose que tu l'as vu, du coup je vois pas trop ce que tu veux dire en fait. Faut pas que je rajoute une horloge quand même, ou alors des conditions de front montant??

Reply

Marsh Posté le 27-03-2012 à 12:33:42    

Oops j'avais pas vu effectivement ta machine d'état est cadencée, mais pas le reste (il y a beaucoup de boucle combinatoires, il faudrait cadencer le process complet ou utiliser des next_xxx pour beacoup de signaux);
 
Un petit conseil utilise rising_edge(clk) au lieu de (clk'event and clk='1').
 
Ta FIFO n'est pas sur front montant, il faut corriger ça (actuellement tu infère une latch, ce qui est dangereux)


---------------
sheep++
Reply

Marsh Posté le 27-03-2012 à 13:43:08    

Je m'execute, tient pourquoi c'est mieux le rising edge plus que le clk'event and clk='1' ?
 
Simple precision : Par next_xxx tu entends les signaux temporaires qu'on utilise pendant le process et qu'on affecte a la fin c'est ca??
(dsl pour l'orthographe mais clavier allemand...)

Reply

Marsh Posté le 27-03-2012 à 15:16:07    

L'avantage n'est pas gigantesque, mais c'est une bonne habitude à prendre:
http://vhdlguru.blogspot.se/2010/0 [...] k-and.html

 

Effectivement par next_xxx j'entends bien le signal combinatoire qui entre dans la bascule.
Mais il est plus facilement maintenable, plus simple, et comporte moins de ligne de code de tout simplement cadencer (en entourant le fonctionnel du if rst then ... elsif rising_edge then ... end if) le process qui te fait tous tes calculs... Enfin quand tu l'aura simplifié ce sera plus simple ;)


Message édité par h3bus le 27-03-2012 à 15:18:41

---------------
sheep++
Reply

Marsh Posté le 27-03-2012 à 17:07:20    

Bon j'ai essayé de tout cadencer, j'ai donc mis des blocs if reset ... aux endroits où j'appelais des fonctions. Pour le reset je savais pas trop, donc lorsque le reset passe à un on retourne à l'IDLE. Voilà dis moi ce que t'en pense.

Code :
  1. library IEEE;
  2. use IEEE.std_logic_1164.all;
  3. use IEEE.numeric_std.all;
  4.  
  5.  
  6. entity brute_force is
  7.    port (
  8.    a_reset_l       : in  std_logic;
  9.    clk             : in  std_logic;
  10.    start_h         : in  std_logic;
  11.    order           : in  std_logic_vector( 3 downto 0);
  12.    data_o          : out std_logic_vector( 7 downto 0);
  13.    );
  14. end entity brute_force;
  15.  
  16. architecture rtl_vhdl of brute_force is
  17.  
  18.  
  19. --Functions The sames functions which are made in the systemc file(Masking)
  20.  
  21. function is_set(mask:integer; pos:integer) return std_logic_vector is--With this function I can know if a bit is '1'
  22.    variable mk:std_logic_vector((TO_INTEGER(UNSIGNED(order))-1) downto 0);
  23.    variable temp1: std_logic_vector ((TO_INTEGER(UNSIGNED(order))-1) downto 0);
  24.    variable temp2: UNSIGNED ((TO_INTEGER(UNSIGNED(order))-1) downto 0);
  25.   begin  
  26.  
  27.    temp1:=std_logic_vector(TO_UNSIGNED(mask,(TO_INTEGER(UNSIGNED(order)))));--I convert a integer '1' into a vector of 49 bits
  28.    temp2:=(TO_UNSIGNED(1,(TO_INTEGER(UNSIGNED(order)))));--convert the value of mask into a vector of 49 bits
  29.  
  30.    mk:= temp1 and std_logic_vector(temp2 rol pos);
  31.    return mk;
  32. end is_set;
  33.  
  34.  
  35. function do_set(mask: integer; pos: integer) return integer is--With this procedure I can set a bit in the position indicated by pos.
  36.    variable temp1: UNSIGNED ((TO_INTEGER(UNSIGNED(order))-1) downto 0);
  37.    variable mask1:integer;
  38.     begin
  39.         temp1:=(TO_UNSIGNED(mask,(TO_INTEGER(UNSIGNED(order)))));
  40.         mask1:=TO_INTEGER((temp1 or (temp1 rol pos)));
  41.    return mask1;
  42. end do_set;
  43.  
  44. function do_unset(mask: integer ;  pos: integer ) return integer is
  45.    variable temp2: UNSIGNED ((TO_INTEGER(UNSIGNED(order))-1) downto 0);
  46.    variable mask2:integer;
  47. begin
  48.    temp2:=(TO_UNSIGNED(mask,(TO_INTEGER(UNSIGNED(order)))));--With this function I clear set a bit in the position indicated by pos.
  49.    mask2:=TO_INTEGER((temp2 and (not(temp2 rol pos))));
  50.    return mask2;
  51. end do_unset;
  52.  
  53. component LIFO
  54.             
  55.          data_i   : in  std_logic_vector(7 downto 0);
  56.         data_o  : out std_logic_vector(7 downto 0);
  57.         Rd,Wr     : in  std_logic;            
  58.         Empty,Full: out std_logic;    
  59.         Clk       : in  std_logic
  60.          size           : in integer);
  61. end component;
  62.  
  63.  
  64.  
  65. type mask is array (integer range<> ) of integer;
  66. signal row_mask : mask(0 to (TO_INTEGER(UNSIGNED(order))-1));
  67. signal col_mask : mask(0 to (TO_INTEGER(UNSIGNED(order))-1));
  68. signal sqr_mask : mask(0 to (TO_INTEGER(UNSIGNED(order))-1));
  69.  
  70.  
  71. type State is (IDLE, EMPTY_CASE, FILL, TEST,UNSET, SOLVE)
  72.  
  73. signal b : integer;--number of blocks
  74. signal row :integer;
  75. signal col : integer;
  76. signal n : integer;--
  77. signal zero : std_logic_vector(48 downto 0) := (others=>'0');
  78. signal sqr_index : integer;
  79. type sudoku is array (integer range<> ) of integer;
  80. signal matrix_sudoku : sudoku(0 to 2400);
  81.  
  82. signal State: State;
  83. signal State: NextState;
  84. signal valid:std_logic;
  85. signal found:std_logic;
  86. signal conflict:std_logic;
  87. signal allFilled:std_logic;
  88. signal start:std_logic;
  89. signal LIFO_out:std_logic_vector(7 downto 0);
  90. signal i:integer := '0';
  91. signal LIFO_FULL:std_logic;
  92. signal LIFO_EMPTY:std_logic;
  93. signal LIFO_read:std_logic;
  94. signal LIFO_write:std_logic;
  95. signal is_set_row:std_logic;
  96. signal is_set_col:std_logic;
  97. signal is_set_sqr:std_logic;
  98.  
  99. LIFO port map(data_i => matrix_sudoku(row*b + col),
  100.               data_o =>LIFO_out,
  101.               Full => LIFO_FULL,
  102.               Empty =>LIFO_EMPTY,
  103.               Rd => LIFO_read,
  104.               Wr => LIFO_write,
  105.               Clk => clk,
  106.               size => n);
  107.                                 
  108. begin
  109.    process(clk, a_reset_l)
  110.    begin
  111.        if (a_reset_l = '0') then
  112.            State <= IDLE;
  113.        elsif (rising_edge(clk)) then
  114.            State <= NextState;
  115.        end if;
  116.    end process;
  117.  
  118.    process(State, NextState, start, found, col, row, valid, conflict, LIFO_out, allFiled)
  119.  
  120.     b <= TO_INTEGER(UNSIGNED(order));
  121.     n <= b*b;
  122.     col <= '0';
  123.     row <= '0';
  124.    begin
  125.        case state is
  126.            when IDLE =>
  127.                if(start/= '0') then NextState <= EMPTY_CASE;
  128.                else NextState <= IDLE;
  129.                end if;
  130.          
  131.            when EMPTY_CASE =>
  132.                 
  133.                if(matrix_sudoku(row*b + col) = 0) then
  134.                    found <= '1';
  135.                 else col <= col + '1';
  136.                 end if;
  137.                 
  138.                if(found = '1') then NextState <= FILL;
  139.                elsif(col = n) then row <= row + '1';
  140.                                    col <= '0';
  141.                elsif(row = n or LIFO_FULL = '1') then allFiled <= '1';
  142.                                    NextState <= SOLVE;
  143.                end if;
  144.                 
  145.          
  146.            when FILL =>
  147.                 i <= i + '1';
  148.                 if( i < n)
  149.                     if (a_reset_l = '1') then
  150.                         State <= IDLE;
  151.                     elsif (rising_edge(clk)) then
  152.                         is_set_row <= is_set(row_mask(row),i);
  153.                         is_set_col <= is_set(col_mask(col),i);
  154.                         is_set_sqr <= is_set(sqr_mask(sqr_index),i);
  155.                     end if;
  156.                     
  157.                     if( (is_set_row or is_set_col or is_set_sqr) \= zero) then valid <= '1';
  158.                     else conflict <= '1';
  159.                     end if;
  160.                 
  161.                     if (a_reset_l = '1') then
  162.                         State <= IDLE;
  163.                     elsif (rising_edge(clk)) then
  164.                         row_mask(row)<= do_set(row_mask(row),i);
  165.                         col_mask(col)<=do_set(col_mask(col),i);
  166.                         sqr_mask(sqr_index)<=do_set(sqr_mask(sqr_index),i);
  167.                         matrix_sudoku(row*b + col)<= i;
  168.                     end if;
  169.                     
  170.                     LIFO_read <= '0';
  171.                     LIFO_write <= '1';
  172.                     
  173.                     if(col < n) then col <= col + '1';
  174.                     end if;
  175.                     
  176.                     if(valid = '1' and LIFO_FULL = '1') then NextState <= EMPTY_CASE;
  177.                                                              data_o <= LIFO_out;
  178.                     elsif(conflict = '1') then NextState <= TEST;  
  179.                     end if;
  180.                 else NextState <= SOLVE;
  181.                 end if;
  182.          
  183.            when TEST =>
  184.                 LIFO_read <= '1';
  185.                 LIFO_write <= '0';
  186.                 if( TO_INTEGER(UNSIGNED(LIFO_out) = n)) then NextState <= UNSET;
  187.                 else NextState <= FILL;
  188.                         valid <= '1';
  189.                 end if;
  190.                
  191.             when UNSET =>
  192.                     if (a_reset_l = '1') then
  193.                         State <= IDLE;
  194.                     elsif (rising_edge(clk)) then
  195.                         matrix_sudoku(row*b + col)<= 0;
  196.                         row_mask(row)<= do_unset(row_mask(row),i);
  197.                         col_mask(col)<=do_unset(col_mask(col),i);
  198.                         sqr_mask(sqr_index)<=do_unset(sqr_mask(sqr_index),i);
  199.                     end if;
  200.                
  201.                 NextState <= TEST;
  202.              
  203.            when SOLVE =>
  204.                NextState <= IDLE;
  205.          
  206.            when others =>
  207.                NextState<=IDLE;
  208.        end case;
  209.      
  210.    end process;
  211. end process;
  212. end architecture;


Message édité par Gefroren le 28-03-2012 à 16:05:55
Reply

Marsh Posté le 27-03-2012 à 19:47:30    

C'est trop compliqué pour que je t'indique ou sont les soucis, problème par problème.

 

Je te conseille de commencer par faire un seul petit bout simple (et sans utiliser les fonctions), je t'aiderai à corriger et améliorer la syntaxe puis on rajoutera petit bout par petit bout.

 

Dis toi bien que si ça ne synthétise pas, il y a un soucis (et là ça va pas synthétiser).

 

Donc simplifie, poste un code (utilise les balise de code "ada", de mémoire ça marche sur HFR et c'est très proche de VHDL), mais seulement si ça synthétise (ou si tu ne sais pas pourquoi ça ne synthétise pas) à partir de là je pourrai t'aider.

 

Courage, ce que tu essaies de faire est compliqué, même pour un as du VHDL, mais avec de la méthode tu vas y arriver.


Message édité par h3bus le 27-03-2012 à 19:48:41

---------------
sheep++
Reply

Marsh Posté le 28-03-2012 à 00:27:31    

Arf... Ok, merci pour ton aide en tout cas.
Il y a un écueil à tout ça, c'est que ce projet je dois le rendre avant le 1er avril et donc bon je pense que ça va être short. De plus vu que je suis en stage en même temps en ce moment j'ai pas le temps d'aller à la FAC, du coup je dois bosser de chez moi. Le truc c'est qu'ici ils utilisent ICPRO sous Solaris et que c'est super super lent, alors en SSH chez moi c'est juste pas possible.
Tout ce que je t'ai montré, je l'ai fait direct avec Notepad, sinon c'est trop trop long. Du coup je peux pas tester, ou alors je dois prévoir la demi-heure juste pour un test.
Enfin bref c'est pas grave j'ai déjà pas mal de choses à expliquer et mon Belegarbeit (genre de rapport) sera convenablement fourni (sauf que y'aura pas de simulation, bien entendu)
En tout cas tu m'as vachement aidé, et je te remercie pour ça.
 
Au fait les balises Ada, ça marche pas non plus.

Reply

Marsh Posté le 28-03-2012 à 00:46:20    

Cf bbcode, bon c'est pas idéal mais ça marchotte...
 

Code :
  1. process(clk, rst_n)
  2. begin
  3.  if then
  4. end process;


 
Ah mais laisse tomber pour le premier avril c'est infaisable si tu n'y passe pas plus de temps.
 
Tu peux toujours télécharger chez toi l'ide altera ou xilinx, il y a des version gratuites et tu pourras synthétiser et simuler.
Je voies bien que tu n'a pas pu tester pour l'instant, même si c'est très dur de faire ça pour le 1er, ça vaut le coup de s'y pencher plus tard, surtout si tu penses faire du HDL ou du design électronique plus tard!


---------------
sheep++
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed