Greboca  

DLFP - Dépêches  -  TapTempo en Verilog

 -  23 septembre - 

Le projet TapTempo semble faiblir depuis quelques mois maintenant. En panne de langage informatique pour en faire une dépêche ?

N. D. M. — TapTempo est un détecteur de tempol’utilisateur frappe une touche en cadence régulière et le programme en déduit le tempo correspondant. Il a été décliné en de multiples langages de programmation.

Laissez‑moi vous présenter un langage assez particulier puisqu’il ne sert pas à faire de la programmation. Ce langage permet de décrire le comportement numérique d’un composant électronique (on parle alors de langage de description de matériel — HDL) : le Verilog.

C’est aussi un langage utilisé pour faire de la synthèse numérique sur les circuits logiques programmables (FPGA). Dans cet exemple, nous utiliserons la carte de développement à bas coût ColorLight 5A‑75B.

Vue d’ensemble du montage TapTempo

Sommaire

Le Verilog

Le Verilog est un langage conçu à l’origine pour rédiger des spécifications de circuits logiques en électronique numérique. Le langage permet de décrire le comportement de sortie par rapport à des entrées logiques. Un peu comme les logiciels de saisie de schéma électronique, le Verilog est très hiérarchique, on décrit des modules avec leurs entrées‑sorties. Que l’on assemble ensuite dans d’autres modules pour finir dans un module « top » qui décrit le composant final.

Dans le cas de TapTempo, le module « top » est déclaré comme ceci :

module taptempo #(
    parameter CLK_PER_NS = 40, // 25Mhz clock (ns)
    parameter TP_CYCLE = 5120, // timepulse cycle period (ns)
    parameter BPM_MAX = 250 // BPM max (bpm)
)(
    input clk_i,
    input btn_i,
    output pwm_o
);
//corps du module
endmodule

Le module possède deux entrées : l’horloge (clk_i) et le bouton (btn_i) ainsi qu’une sortie pwm (pwm_o) pour l’affichage. Les paramètres seront vus comme des constantes au moment de la simulation, ils permettent de configurer les composants en fonction de la cible. Le changement de valeur des signaux se fait dans des processus qui sont déclenchés sur événement. Ces processus sont décrits au moyen du mot clef always@() en Verilog.

Par exemple, dans le code suivant :

/* Detect rising edge*/
reg btn_old, btn_rise;
always@(posedge clk_i)
begin
    btn_old <= btn_i;
    if(btn_old == 0 && btn_i == 1)
        btn_rise <= 1;
    else
        btn_rise <= 0;
end

L’événement déclencheur du process est le front montant de l’horloge clk_i. À chaque fois qu’un front montant d’horloge se présente, le processus est exécuté de manière séquentielle.

L’opérateur <= est l’opérateur d’affectation dit « non bloquant ». Cela signifie que la valeur ne sera effectivement appliquée qu’à la fin de l’exécution du process. Donc, la valeur du signal btn_old ne sera pas nécessairement égale à btn_i à la ligne du if() comme on aurait pu instinctivement le croire.

Le langage Verilog a beaucoup de succès dans le monde du logiciel libre. En effet, il est relativement peu verbeux et ressemble au C pour de nombreux aspects. Il est par exemple possible de décrire des macros de la même manière qu’en C, il suffit de remplacer le symbole # par ` pour créer des constantes qui seront remplacées par le préprocesseur :

/* count tap period */
`define MIN_NS 60_000_000_000
`define BTN_PER_MAX (`MIN_NS/TP_CYCLE)
`define BTN_PER_SIZE ($clog2(1 + `BTN_PER_MAX))

Le Verilog reprend également les opérateurs booléen et binaire &, &&, |, ||, etc., du C.

C’est le langage HDL le mieux pris en charge par les différents logiciels libres. Si l’on souhaite se lancer dans le domaine des FPGA et/ou des ASIC, il est préférable de commencer par lui. C’est également le langage « de sortie » de quasiment tous les générateurs de code HDL.

Architecture de TapTempo

L’outil indispensable pour commencer un projet en Verilog est… le papier et le crayon. Il est en effet indispensable d’avoir une vue d’ensemble assez claire de ce que l’on souhaite réaliser avant de se lancer dans le code.

Voici donc l’architecture générale du composant TapTempo :
Schema TapTempo au Crayon

Même si l’on doit revenir plusieurs fois (ce qui est le cas ici puisque les constantes ne sont pas à jour) sur ce schéma général en cours de développement, cette partie est très importante. Si elle est bien pensée, le reste coule de source.

Le composant va nécessiter quelques compteurs, mais l’horloge utilisée ici étant très rapide nous allons d’abord factoriser le comptage au moyen du module nommé timepulse, ce module va distribuer une pulsation qui servira de base aux autres compteurs pour leur fonctionnement interne.

L’entrée utilisateur se compose d’un bouton (touche télégraphique « morse »). Les fronts montant et descendant de cette entrée n’étant pas synchronisés sur l’horloge du système nous allons devoir le faire au moyen de deux bascules en série pour éviter la métastabilité.

/* Synchronize btn_i to avoid metastability*/
reg btn_old, btn_s;
always@(posedge clk_i or posedge rst)
begin
    if(rst) begin
        btn_old <= 1'b0;
        btn_s <= 1'b0;
    end else begin
        btn_old <= btn_i;
        btn_s <= btn_old;
    end
end

Le second problème que pose notre entrée est que l’appui sur le bouton ne génère pas des changements francs de son état. Chaque « appui et relâche » génère une série de rebonds et donc une série de 0 et de 1 avant de se stabiliser. Pour lisser le signal il va donc falloir faire passer le signal dans le bloc « antirebond » debounce.

Le bloc percount va ensuite se charger de mesurer le temps entre deux appuis sur le bouton. Cette période va devoir être transformée en fréquence « BPM » (Beat Per Minute) via le module per2bpm, puis en une valeur pseudo‐analogique (PWM) grâce au module pwmgen.

La carte cible ne possédant pas de bouton « reset », il va falloir le générer grâce au module rstgen de manière à s’assurer de l’état de départ de notre système au démarrage.

Entrée‑sortie

La plupart des programmes TapTempo proposés jusqu’ici supposaient — en plus d’un processeur — la présence d’un clavier et d’une console texte de sortie (avec toute la pile de pilotes et de système d’exploitation associés). Ici, nous allons devoir tout définir dans le « portegramme » — dans l’industrie on va parler d’IP pour Intellectual Property, quel horrible nom.

L’idée est donc de simplifier au maximum l’entrée « clavier » et la sortie histoire de pouvoir les décrire simplement.

Pour l’entrée nous allons nous contenter d’un contact de type bouton, ou d’une touche de type télégraphe « morse » :
TapTempoEntreeMorse

Comme on peut le voir dans le schéma ci‑dessus, quand la touche est appuyée, l’entrée « bouton » est mise à la masse et donne un niveau logique à 0 sur notre système. Lorsque l’on relâche le bouton, la résistance de tirage ramène le niveau de tension à Vcc pour avoir un niveau 1 sur l’entrée.

Pour la sortie, l’idée de mettre un écran complexifie énormément le système. En effet, il est nécessaire de faire une machine d’état assez complexe pour initialiser l’écran puis rafraîchir l’affichage. Il est souvent nécessaire d’ajouter un processeur « soft » rien que pour ça d’ailleurs (bon, il est vrai que le VGA n’est pas si compliqué, mais il reste plus complexe que la solution proposée ici).

Non, l’idée ici est d’utiliser les graduations de l’antique voltmètre à aiguille trouvé dans une cave et qui gradue de 0 à 300 comme on peut le voir sur la photo :
vuemetretaptempo

Et comme un système numérique ne sort que des 0 et des 1 sur ses broches, on va « simuler » une valeur analogique au moyen d’une modulation de largeur d’impulsion, en anglais Pulse Width Modulation — PWM. Il suffit de changer le rapport cyclique entre le temps haut et le temps bas de notre signal pour faire varier la tension moyenne qui sera vue par le voltmètre. Si on l’ajuste correctement avec une résistance en série, il est relativement facile de forcer la valeur maximale (5 V) à 250.

PWM

La période de la modulation de largeur d’impulsion sera configurée suffisamment rapide pour que l’aiguille n’oscille pas.

Pulsation de temporisation (timepulse)

Le module ne prend pas de valeur d’entrée hormis l’horloge et le reset qui sont de rigueur dans tout le projet. Son signal de sortie tp_o est une pulsation de l’horloge émise toutes les 5 120 ns :

module timepulse #(
    parameter CLK_PER_NS = 40,
    parameter PULSE_PER_NS = 5120
)(
    /* clock and reset */
    input clk_i,
    input rst_i,
    /* output */
    output tp_o);

Pour pouvoir compter des périodes de 5 120 ns on définit un registre de comptage :

`define MAX_COUNT (PULSE_PER_NS/CLK_PER_NS)
`define MAX_COUNT_SIZE ($clog2(`MAX_COUNT))

reg [`MAX_COUNT_SIZE-1:0] counter = 0;

Puis on compte de manière synchronisée avec l’horloge :

always@(posedge clk_i or posedge rst_i)
begin
    if(rst_i)
    begin
        counter <= 0;
    end else begin
        if (counter < `MAX_COUNT)
        begin
            counter <= counter + 1'b1;
        end else begin
            counter <= 0;
        end
    end
end

La pulsation est émise lorsque le compteur passe par 0 :

assign tp_o = (counter == 0);

Gestion des rebonds (debounce)

L’entrée de ce module est le signal de bouton préalablement synchronisé avec l’horloge du système btn_s. Le compteur utilisera la pulsation tp_i généré par le module timepulse décrit ci‑avant.

La sortie du module est un signal btn_o proprement lissé. La période de temporisation de 20 ms est donné ici en paramètre DEBOUNCE_PER_NS :

module debounce #(
    parameter PULSE_PER_NS = 5120,
    parameter DEBOUNCE_PER_NS = 20_971_520
)(
    /* clock and reset */
    input clk_i,
    input rst_i,
    /* inputs */
    input tp_i,
    input btn_i,
    /* output */
    output btn_o
);

La gestion des rebonds est réalisée au moyen d’un compteur utilisé pour temporiser :

`define MAX_COUNT ((DEBOUNCE_PER_NS/PULSE_PER_NS)-1'b1)
`define MAX_COUNT_SIZE ($clog2(`MAX_COUNT))

/* Counter */
reg [`MAX_COUNT_SIZE-1:0] counter = 0;

Ainsi que d’une machine d’états à quatre états :

/* State machine */
localparam [1:0] s_wait_low  = 2'h0,
                 s_wait_high = 2'h1,
                 s_cnt_high  = 2'h2,
                 s_cnt_low   = 2'h3;

reg [1:0] state_reg, state_next;

Les transitions de la machine d’états sont données dans le code ci‑dessous dans un processus dit « combinatoire » (always@*) par opposition à un processus « synchrone ».

always@*
begin
    case(state_reg)
        s_wait_low:
            if(btn_i)
                state_next = s_cnt_high;
            else
                state_next = s_wait_low;
        s_wait_high:
            if(!btn_i)
                state_next = s_cnt_low;
            else
                state_next = s_wait_high;
        s_cnt_high:
            /* verilator lint_off WIDTH */
            if(counter == `MAX_COUNT)
            /* verilator lint_on WIDTH */
                state_next = s_wait_high;
            else
                state_next = s_cnt_high;
        s_cnt_low:
            /* verilator lint_off WIDTH */
            if(counter == `MAX_COUNT)
            /* verilator lint_on WIDTH */
                state_next = s_wait_low;
            else
                state_next = s_cnt_low;
    endcase;
end

L’état de la machine est tout de même synchronisé dans un second processus :

always@(posedge clk_i or posedge rst_i)
    if(rst_i)
        state_reg <= s_wait_low;
    else
        state_reg <= state_next;

Le principe de « lissage » des rebonds est donc le suivant : dans l’état initial s_wait_low, on attend que le bouton passe à la valeur 1, et lorsque le signal passe à 1, on change d’état pour s_cnt_high.

Le passage dans l’état s_cnt_high a pour effet de faire passer le signal de sortie à 1 et déclencher le compteur. Tant que le compteur compte et n’a pas atteint la valeur MAX_COUNT, on reste dans cet état quelles que soient les variations du signal d’entrée. Lorsque le compteur atteint la valeur maximale, la machine d’état passe dans l’état s_wait_high (en attente de valeurs hautes).

Dans l’état s_wait_high on surveille la valeur du bouton d’entrée, si elle passe à 0 on change d’état pour s_cnt_low. De manière symétrique à s_cnt_high, on déclenche donc le compteur en ignorant la valeur d’entrée, et, lorsqu’elle atteint son maximum, on passe à l’état initial s_wait_low.

La valeur « lissée » du bouton en sortie est donnée par l’état de la machine d’état :

assign btn_o = (state_reg == s_cnt_high) || (state_reg == s_wait_high);

Mesure de la période de tempo (percount)

L’interface du module percount se compose des entrées habituelles d’horloge clk_i, de reset rst_i, ainsi que de la pulsation tp_i.

Le signal de mesure en entrée est btn_i et la sortie est un vecteur btn_per_o donnant la valeur mesurée. La valeur est considérée comme valide uniquement lorsque la sortie btn_per_valid est à 1. Cette astuce permet d’économiser un registre si la sauvegarde de la valeur mesurée est inutile comme c’est le cas ici.

`define MIN_NS 60_000_000_000
`define BTN_PER_MAX (`MIN_NS/TP_CYCLE)
`define BTN_PER_SIZE ($clog2(1 + `BTN_PER_MAX))

module percount #(
    parameter CLK_PER_NS = 40,
    parameter TP_CYCLE = 5120,
    parameter PULSE_PER_NS = 5120,
)(
    /* clock and reset */
    input clk_i,
    input rst_i,
    /* time pulse */
    input tp_i,
    /* input button */
    input btn_i,
    /* output period */
    output [(`BTN_PER_SIZE-1):0] btn_per_o,
    output btn_per_valid);

Maintenant que nous avons un signal de bouton btn_b propre et lissé, nous pouvons entamer la mesure de la période entre deux appuis au moyen de… devinez quoi ? D’un compteur pardi !

reg [($clog2(`BTN_PER_MAX+1)-1):0] counter = 0;
reg counter_valid = 0;

assign btn_per_valid = counter_valid;
assign btn_per_o = counter;

Il nous faut tout d’abord détecter le front descendant du bouton :

reg btn_old;
wire btn_fall = btn_old & (!btn_i);

always@(posedge clk_i or posedge rst_i)
begin
    if(rst_i)
        btn_old <= 1'b0;
    else
        btn_old <= btn_i;     
end

Le signal btn_fall sert de remise à zéro du compteur ainsi que de validation de la valeur de sortie :

always@(posedge clk_i or posedge rst_i)
begin
    if(rst_i)
    begin
        counter <= 0;
    end else begin
        if(btn_fall) begin
            counter_valid <= 1'b1;
        end else if(counter_valid) begin
            counter <= 0;
            counter_valid <= 1'b0;
        end else begin
            /* stop counting if max, count tp_i */
            if(tp_i && counter < `BTN_PER_MAX)
                counter <= counter + 1'b1;
        end
    end
end

Le compteur compte le nombre de pulsations de tp_i jusqu’à atteindre la saturation BTN_PER_MAX. Si un front montant du bouton se présente avec btn_fall, on valide le compteur avec counter_valid. Et si le signal de validation passe à 1 (donc, le coup d’horloge suivant), on remet le compteur à zéro et on recommence à compter.

Calcul de la fréquence en Beat Per Minute (per2bpm)

Avec le module per2bpm on arrive dans la partie critique du projet, car il va nous falloir faire une division. On entre une période dans le module :

    /* inputs */
    input [(`BTN_PER_SIZE-1):0] btn_per_i,
    input btn_per_valid,

Et on doit en ressortir une fréquence (BPM) :

    /* outputs */
    output [`BPM_SIZE - 1:0] bpm_o,
    output bpm_valid

Suivant la formule :

Il faut donc diviser la constante <img style="display: inline; max-height: 1em;" class="mathjax" src="data:image/svg+xml;base64,PHN2ZyB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlu%0AayIgdmlld0JveD0iMCAtMTAwMC43MTE5MDAxNDUyOTQ3IDMwMTAuMjM2MjE1%0AODg3MTggMTUwMS40MjM4MDAyOTA1ODk1IiBzdHlsZT0id2lkdGg6IDYuOTg4%0AZXg7IGhlaWdodDogMy40OTRleDsgdmVydGljYWwtYWxpZ246IC0xLjIwNWV4%0AOyBtYXJnaW46IDFweCAwcHg7IHBvc2l0aW9uOiBzdGF0aWM7IiB4bWxucz0i%0AaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxkZWZzIGlkPSJNYXRoSmF4%0AX1NWR19nbHlwaHMiPjxwYXRoIGlkPSJTVElYV0VCTUFJTkktNEQiIHN0cm9r%0AZS13aWR0aD0iMTAiIGQ9Ik04NzIgNjUzdi0xNmMtNTcgLTkgLTY3IC0yMyAt%0AODEgLTc0bC0xMjMgLTQ0M2MtNyAtMjUgLTE0IC00NiAtMTQgLTYyYzAgLTI2%0AIDE4IC00MCA4MSAtNDJsLTEgLTE2aC0yNzF2MTZjNjUgNyA4NSAyNCAxMDIg%0AODZsMTI2IDQ1OWwtMzc2IC01NjFoLTE3bC02MiA1NDZsLTExOCAtNDI4Yy01%0AIC0xOCAtOSAtNDMgLTkgLTU0YzAgLTI4IDE5IC00NCA3MCAtNDh2LTE2aC0x%0AOTd2MTZjNTIgNiA2OCAyMiAxMDAgMTM0bDExNCA0MDEgYzggMjcgMTIgNDQg%0AMTIgNTJjMCAxOSAtMjQgMzEgLTc0IDM0djE2aDE4MWw1NiAtNDkybDMzNSA0%0AOTJoMTY2WiI+PC9wYXRoPjxwYXRoIGlkPSJTVElYV0VCTUFJTkktNDkiIHN0%0Acm9rZS13aWR0aD0iMTAiIGQ9Ik0zODQgNjUzdi0xNmMtNTYgLTcgLTY1IC0x%0ANiAtODIgLTc3bC0xMjAgLTQyOWMtOSAtMzIgLTE1IC01NiAtMTUgLTc2YzAg%0ALTI4IDEyIC0zMiA2OSAtMzl2LTE2aC0yNDR2MTZjNTUgMTAgNjkgMTkgODQg%0ANzVsMTIwIDQ0MWM3IDI1IDEzIDQ2IDEzIDYyYzAgMjUgLTE2IDQwIC03MiA0%0AM3YxNmgyNDdaIj48L3BhdGg+PHBhdGggaWQ9IlNUSVhXRUJNQUlOSS00RSIg%0Ac3Ryb2tlLXdpZHRoPSIxMCIgZD0iTTcyNyA2NTN2LTE2Yy02MyAtMTQgLTY1%0AIC0xNiAtMTAyIC0xNDVsLTE0NiAtNTA3aC0xOGwtMjMwIDU1MGwtMTE0IC00%0AMjJjLTYgLTIxIC05IC00MSAtOSAtNTRjMCAtMjggMTggLTM5IDcwIC00M3Yt%0AMTZoLTE5OHYxNmM1NiA4IDcwIDI0IDEwNiAxNTJsMTE3IDQxNWMtMTUgMzUg%0ALTM5IDU0IC04NiA1NHYxNmgxNjBsMjA3IC00OTlsMTA2IDM4OGM2IDIxIDgg%0AMzIgOCA0NGMwIDM2IC0xMiA0NiAtNjkgNTF2MTZoMTk4WiI+PC9wYXRoPjxw%0AYXRoIGlkPSJTVElYV0VCTUFJTi01RiIgc3Ryb2tlLXdpZHRoPSIxMCIgZD0i%0ATTUwMCAtMTI1aC01MDB2NTBoNTAwdi01MFoiPjwvcGF0aD48cGF0aCBpZD0i%0AU1RJWFdFQk1BSU5JLTRFIiBzdHJva2Utd2lkdGg9IjEwIiBkPSJNNzI3IDY1%0AM3YtMTZjLTYzIC0xNCAtNjUgLTE2IC0xMDIgLTE0NWwtMTQ2IC01MDdoLTE4%0AbC0yMzAgNTUwbC0xMTQgLTQyMmMtNiAtMjEgLTkgLTQxIC05IC01NGMwIC0y%0AOCAxOCAtMzkgNzAgLTQzdi0xNmgtMTk4djE2YzU2IDggNzAgMjQgMTA2IDE1%0AMmwxMTcgNDE1Yy0xNSAzNSAtMzkgNTQgLTg2IDU0djE2aDE2MGwyMDcgLTQ5%0AOWwxMDYgMzg4YzYgMjEgOCAzMiA4IDQ0YzAgMzYgLTEyIDQ2IC02OSA1MXYx%0ANmgxOThaIj48L3BhdGg+PHBhdGggaWQ9IlNUSVhXRUJNQUlOSS01MyIgc3Ry%0Ab2tlLXdpZHRoPSIxMCIgZD0iTTUwOCA2NjdsLTQwIC0yMDBsLTE4IDNjMCAx%0AMDIgLTIyIDE2MyAtMTE5IDE2M2MtNjkgMCAtMTEyIC0zNyAtMTEyIC0xMDBj%0AMCAtNDkgOCAtNjUgOTkgLTE1NmM5MSAtOTIgMTEzIC0xMzUgMTEzIC0yMDBj%0AMCAtMTE0IC04NyAtMTk1IC0yMDIgLTE5NWMtMzEgMCAtNTggNyAtMTA0IDIz%0AYy0yNyAxMCAtMzYgMTIgLTQ3IDEyYy0yMCAwIC0zNiAtOSAtNDMgLTMyaC0x%0AOGwzNCAyMjRsMjAgLTJjLTIgLTkgLTIgLTE2IC0yIC0yMyBjMCAtOTggNjAg%0ALTE2NyAxNDQgLTE2N2M3NyAwIDEzMSA1MiAxMzEgMTI4YzAgNDMgLTE0IDcz%0AIC02MCAxMjNsLTM5IDQyYy0xNCAxNSAtMjYgMjkgLTM5IDQyYy02MCA2NCAt%0ANzUgOTYgLTc1IDE1MGMwIDEwNSA4MiAxNjQgMTc4IDE2NGMzMSAwIDY0IC01%0AIDg1IC0xNGMyMSAtOCAzMyAtMTEgNDYgLTExYzIyIDAgMzEgNSA0NSAyNmgy%0AM1oiPjwvcGF0aD48cGF0aCBpZD0iU1RJWFdFQk1BSU5JLTU0IiBzdHJva2Ut%0Ad2lkdGg9IjEwIiBkPSJNNjMzIDY1M2wtNDQgLTE2NGwtMTcgMmMyIDE3IDMg%0AMzMgMyA0NmMwIDUzIC0zNiA4MSAtMTAxIDgxaC01OGwtMTM3IC00OTBjLTYg%0ALTIxIC0xNCAtNDQgLTE0IC02NmMwIC0zMSAxMiAtMzkgNTMgLTQzbDM1IC0z%0Adi0xNmgtMjg4djE2YzY5IDYgOTIgMjEgMTA3IDc1bDE0MyA1MjdjLTE1OCAw%0AIC0xOTAgLTE2IC0yMzggLTEyNGwtMTggNGw0MiAxNTVoNTMyWiI+PC9wYXRo%0APjxwYXRoIGlkPSJTVElYV0VCTUFJTkktNTAiIHN0cm9rZS13aWR0aD0iMTAi%0AIGQ9Ik0xNDYgNjUzaDI0MWMxNDcgMCAyMTggLTUyIDIxOCAtMTQ4YzAgLTU0%0AIC0yNyAtMTA5IC02OCAtMTQzYy00NiAtMzggLTExNiAtNTcgLTIwNSAtNTdj%0ALTQyIDAgLTY0IDIgLTkwIDhsLTUzIC0xOTNjLTcgLTI3IC0xNCAtNDggLTE0%0AIC02M2MwIC0yMyAxNSAtMzUgNjkgLTQxdi0xNmgtMjQ0djE2YzU3IDggNjYg%0AMTcgODQgODJsMTE2IDQxNGMxMyA0NyAxNyA2OCAxNyA4M2MwIDI3IC0xNCAz%0ANSAtNzEgNDJ2MTZ6TTMyMCA1OTJsLTY5IC0yNDUgYzI5IC01IDM0IC01IDUy%0AIC01YzYyIDAgOTcgNiAxMjggMjRjNDQgMjUgNzEgNjkgNzEgMTM0YzAgODkg%0ALTQ4IDEyMyAtMTMwIDEyM2MtMjggMCAtNDYgLTggLTUyIC0zMVoiPjwvcGF0%0AaD48cGF0aCBpZD0iU1RJWFdFQk1BSU4tNUYiIHN0cm9rZS13aWR0aD0iMTAi%0AIGQ9Ik01MDAgLTEyNWgtNTAwdjUwaDUwMHYtNTBaIj48L3BhdGg+PHBhdGgg%0AaWQ9IlNUSVhXRUJNQUlOSS00RSIgc3Ryb2tlLXdpZHRoPSIxMCIgZD0iTTcy%0ANyA2NTN2LTE2Yy02MyAtMTQgLTY1IC0xNiAtMTAyIC0xNDVsLTE0NiAtNTA3%0AaC0xOGwtMjMwIDU1MGwtMTE0IC00MjJjLTYgLTIxIC05IC00MSAtOSAtNTRj%0AMCAtMjggMTggLTM5IDcwIC00M3YtMTZoLTE5OHYxNmM1NiA4IDcwIDI0IDEw%0ANiAxNTJsMTE3IDQxNWMtMTUgMzUgLTM5IDU0IC04NiA1NHYxNmgxNjBsMjA3%0AIC00OTlsMTA2IDM4OGM2IDIxIDggMzIgOCA0NGMwIDM2IC0xMiA0NiAtNjkg%0ANTF2MTZoMTk4WiI+PC9wYXRoPjxwYXRoIGlkPSJTVElYV0VCTUFJTkktNTMi%0AIHN0cm9rZS13aWR0aD0iMTAiIGQ9Ik01MDggNjY3bC00MCAtMjAwbC0xOCAz%0AYzAgMTAyIC0yMiAxNjMgLTExOSAxNjNjLTY5IDAgLTExMiAtMzcgLTExMiAt%0AMTAwYzAgLTQ5IDggLTY1IDk5IC0xNTZjOTEgLTkyIDExMyAtMTM1IDExMyAt%0AMjAwYzAgLTExNCAtODcgLTE5NSAtMjAyIC0xOTVjLTMxIDAgLTU4IDcgLTEw%0ANCAyM2MtMjcgMTAgLTM2IDEyIC00NyAxMmMtMjAgMCAtMzYgLTkgLTQzIC0z%0AMmgtMThsMzQgMjI0bDIwIC0yYy0yIC05IC0yIC0xNiAtMiAtMjMgYzAgLTk4%0AIDYwIC0xNjcgMTQ0IC0xNjdjNzcgMCAxMzEgNTIgMTMxIDEyOGMwIDQzIC0x%0ANCA3MyAtNjAgMTIzbC0zOSA0MmMtMTQgMTUgLTI2IDI5IC0zOSA0MmMtNjAg%0ANjQgLTc1IDk2IC03NSAxNTBjMCAxMDUgODIgMTY0IDE3OCAxNjRjMzEgMCA2%0ANCAtNSA4NSAtMTRjMjEgLTggMzMgLTExIDQ2IC0xMWMyMiAwIDMxIDUgNDUg%0AMjZoMjNaIj48L3BhdGg+PC9kZWZzPjxnIHN0cm9rZT0iYmxhY2siIGZpbGw9%0AImJsYWNrIiBzdHJva2Utd2lkdGg9IjAiIHRyYW5zZm9ybT0ibWF0cml4KDEg%0AMCAwIC0xIDAgMCkiPjxnIHRyYW5zZm9ybT0idHJhbnNsYXRlKDEyMCwwKSI+%0APHJlY3Qgc3Ryb2tlPSJub25lIiB3aWR0aD0iMjc3MCIgaGVpZ2h0PSI2MCIg%0AeD0iMCIgeT0iMjIwIj48L3JlY3Q+PGcgdHJhbnNmb3JtPSJ0cmFuc2xhdGUo%0ANjAsNTAyKSI+PHVzZSB0cmFuc2Zvcm09InNjYWxlKDAuNzA3MTA2NzgxMTg2%0ANTQ3NikiIHhsaW5rOmhyZWY9IiNTVElYV0VCTUFJTkktNEQiPjwvdXNlPjx1%0Ac2UgdHJhbnNmb3JtPSJzY2FsZSgwLjcwNzEwNjc4MTE4NjU0NzYpIiB4bGlu%0AazpocmVmPSIjU1RJWFdFQk1BSU5JLTQ5IiB4PSI4NzciIHk9IjAiPjwvdXNl%0APjx1c2UgdHJhbnNmb3JtPSJzY2FsZSgwLjcwNzEwNjc4MTE4NjU0NzYpIiB4%0AbGluazpocmVmPSIjU1RJWFdFQk1BSU5JLTRFIiB4PSIxMjY1IiB5PSIwIj48%0AL3VzZT48dXNlIHRyYW5zZm9ybT0ic2NhbGUoMC43MDcxMDY3ODExODY1NDc2%0AKSIgeGxpbms6aHJlZj0iI1NUSVhXRUJNQUlOLTVGIiB4PSIxOTk4IiB5PSIw%0AIj48L3VzZT48dXNlIHRyYW5zZm9ybT0ic2NhbGUoMC43MDcxMDY3ODExODY1%0ANDc2KSIgeGxpbms6aHJlZj0iI1NUSVhXRUJNQUlOSS00RSIgeD0iMjUwMyIg%0AeT0iMCI+PC91c2U+PHVzZSB0cmFuc2Zvcm09InNjYWxlKDAuNzA3MTA2Nzgx%0AMTg2NTQ3NikiIHhsaW5rOmhyZWY9IiNTVElYV0VCTUFJTkktNTMiIHg9IjMy%0AMzUiIHk9IjAiPjwvdXNlPjwvZz48ZyB0cmFuc2Zvcm09InRyYW5zbGF0ZSgz%0AMjMsLTM4NikiPjx1c2UgdHJhbnNmb3JtPSJzY2FsZSgwLjcwNzEwNjc4MTE4%0ANjU0NzYpIiB4bGluazpocmVmPSIjU1RJWFdFQk1BSU5JLTU0Ij48L3VzZT48%0AdXNlIHRyYW5zZm9ybT0ic2NhbGUoMC43MDcxMDY3ODExODY1NDc2KSIgeGxp%0Abms6aHJlZj0iI1NUSVhXRUJNQUlOSS01MCIgeD0iNjM4IiB5PSIwIj48L3Vz%0AZT48dXNlIHRyYW5zZm9ybT0ic2NhbGUoMC43MDcxMDY3ODExODY1NDc2KSIg%0AeGxpbms6aHJlZj0iI1NUSVhXRUJNQUlOLTVGIiB4PSIxMjU0IiB5PSIwIj48%0AL3VzZT48dXNlIHRyYW5zZm9ybT0ic2NhbGUoMC43MDcxMDY3ODExODY1NDc2%0AKSIgeGxpbms6aHJlZj0iI1NUSVhXRUJNQUlOSS00RSIgeD0iMTc1OSIgeT0i%0AMCI+PC91c2U+PHVzZSB0cmFuc2Zvcm09InNjYWxlKDAuNzA3MTA2NzgxMTg2%0ANTQ3NikiIHhsaW5rOmhyZWY9IiNTVElYV0VCTUFJTkktNTMiIHg9IjI0OTEi%0AIHk9IjAiPjwvdXNlPjwvZz48L2c+PC9nPjwvc3ZnPg==%0A" alt="\frac{MIN\_NS}{TP\_NS}"> par la variable <img style="display: inline; max-height: 1em;" class="mathjax" src="data:image/svg+xml;base64,PHN2ZyB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlu%0AayIgdmlld0JveD0iMCAtNzEyLjI3NzQ4OTAwMjU0MSAzOTc5IDk0Ni41NTQ5%0ANzgwMDUwODE4IiBzdHlsZT0id2lkdGg6IDkuMjc3ZXg7IGhlaWdodDogMi4x%0ANjlleDsgdmVydGljYWwtYWxpZ246IC0wLjYwMmV4OyBtYXJnaW46IDFweCAw%0AcHg7IHBvc2l0aW9uOiBzdGF0aWM7IiB4bWxucz0iaHR0cDovL3d3dy53My5v%0AcmcvMjAwMC9zdmciPjxkZWZzIGlkPSJNYXRoSmF4X1NWR19nbHlwaHMiPjxw%0AYXRoIGlkPSJTVElYV0VCTUFJTkktNjIiIHN0cm9rZS13aWR0aD0iMTAiIGQ9%0AIk0xNjMgMjkwaDFjNjggMTEzIDEyMyAxNTEgMTkzIDE1MWM2NyAwIDExNiAt%0ANDMgMTE2IC0xMjBjMCAtMTU4IC0xNjUgLTMzMiAtMzIwIC0zMzJjLTU3IDAg%0ALTEzMCAyMyAtMTMwIDUzdjZsMTQyIDUyM2M2IDI0IDkgMzggOSA0N2MwIDIy%0AIC01IDIzIC02NCAyNXYxN2M2NyA4IDEwMyAxNCAxNTMgMjNsNSAtNWwtMjEg%0ALTgyek0zODggMzA2YzAgNjEgLTI2IDg2IC03MCA4NmMtNDggMCAtOTQgLTQy%0AIC0xMzcgLTExNSBjLTQ0IC03NCAtNzIgLTE3MSAtNzIgLTIzMWMwIC0yMyAx%0ANSAtMzQgNDYgLTM0YzQzIDAgODYgMjEgMTIzIDU5YzYwIDYyIDExMCAxNjEg%0AMTEwIDIzNVoiPjwvcGF0aD48cGF0aCBpZD0iU1RJWFdFQk1BSU5JLTc0IiBz%0AdHJva2Utd2lkdGg9IjEwIiBkPSJNMjk2IDQyOGwtNSAtMzJoLTg0bC04NyAt%0AMzI4Yy0xIC00IC0yIC0xMSAtMiAtMTRjMCAtMTMgNiAtMTYgMTUgLTE2YzE2%0AIDAgMzIgMTYgODEgNzlsMTMgLTdjLTYwIC05MiAtOTEgLTEyMSAtMTQzIC0x%0AMjFjLTI3IDAgLTQ2IDEyIC00NiAzN2MwIDExIDggNDIgMTYgNzRsNzggMjk2%0AaC03NWMtMSAzIC0xIDYgLTEgNmMwIDExIDkgMjAgMzMgMjVjMzIgNyA5NyA1%0ANiAxMzMgMTEwYzQgNiAxMCA5IDE0IDljNiAwIDkgLTMgOSAtOCBjMCAwIDAg%0ALTUgLTEgLTdsLTI4IC0xMDNoODBaIj48L3BhdGg+PHBhdGggaWQ9IlNUSVhX%0ARUJNQUlOSS02RSIgc3Ryb2tlLXdpZHRoPSIxMCIgZD0iTTQ2MCAxMTdsMTQg%0ALTEzYy02OCAtOTMgLTkzIC0xMTMgLTE0MCAtMTEzYy0yNSAwIC00NyAxNiAt%0ANDcgNTRjMCAxMCAyIDIzIDE2IDc1bDQ0IDE2MmM4IDMxIDE0IDY3IDE0IDc5%0AYzAgMTggLTkgMjkgLTI0IDI5Yy00MCAwIC04NSAtNDkgLTE0OCAtMTQyYy00%0ANSAtNjcgLTUzIC05MCAtMTAwIC0yNDhoLTc1bDk2IDM1MGMxIDUgMiAxMSAy%0AIDE3YzAgMjAgLTE0IDI2IC02NSAyN3YxNmM4MSAxNiAxMDkgMjAgMTYyIDMx%0AbDQgLTJsLTY3IC0yMTggYzEwMCAxNjAgMTY3IDIyMCAyMzEgMjIwYzQzIDAg%0ANjUgLTI1IDY1IC02MWMwIC0xOCAtNCAtMzkgLTEwIC02MGwtNTYgLTIwM2Mt%0AMTAgLTM2IC0xNCAtNTMgLTE0IC02MWMwIC05IDQgLTE4IDE2IC0xOGMxNCAw%0AIDMyIDE2IDYxIDUzYzcgOCAxNCAxNyAyMSAyNloiPjwvcGF0aD48cGF0aCBp%0AZD0iU1RJWFdFQk1BSU4tNUYiIHN0cm9rZS13aWR0aD0iMTAiIGQ9Ik01MDAg%0ALTEyNWgtNTAwdjUwaDUwMHYtNTBaIj48L3BhdGg+PHBhdGggaWQ9IlNUSVhX%0ARUJNQUlOSS03MCIgc3Ryb2tlLXdpZHRoPSIxMCIgZD0iTTIxNSA0MjhsLTI5%0AIC0xMDBjNTQgODEgMTExIDExMyAxNzEgMTEzYzc0IDAgMTE1IC00NyAxMTUg%0ALTEyNWMwIC0xNjUgLTE1MSAtMzI3IC0yOTcgLTMyN2MtMjMgMCAtNDQgNCAt%0ANjkgMTdjLTE3IC03MCAtNDAgLTE1MiAtNDAgLTE2NmMwIC0yMiAxNSAtMjkg%0ANjIgLTI5di0xNmgtMjAzdjE2YzQzIDEgNTYgMTYgNjggNjNsMTE1IDQzMmMx%0AMSA0MCAxNiA2NiAxNiA3MWMwIDI0IC0yOCAyNyAtNDQgMjdoLTIybC0yIDE1%0AbDE1NiAyMiBjMyAwIDUgLTIgNSAtNGMwIDAgLTEgLTUgLTIgLTl6TTM4MiAz%0AMTNjMCA1NyAtMTcgODUgLTYyIDg1Yy01MyAwIC0xMTIgLTU0IC0xMzUgLTEx%0ANGMtMjkgLTc1IC02NSAtMjA0IC02NSAtMjM4YzAgLTIyIDIwIC0zOCA0OCAt%0AMzhjNTMgMCAxMDEgMzMgMTQ1IDk1YzQ4IDY3IDY5IDE0MCA2OSAyMTBaIj48%0AL3BhdGg+PHBhdGggaWQ9IlNUSVhXRUJNQUlOSS02NSIgc3Ryb2tlLXdpZHRo%0APSIxMCIgZD0iTTM1OCAxMDlsMTIgLTEyYy01NyAtNzAgLTEyMSAtMTA4IC0y%0AMDQgLTEwOGMtODEgMCAtMTM1IDU0IC0xMzUgMTM3YzAgMTU1IDE0OSAzMTUg%0AMjk5IDMxNWM1MyAwIDgyIC0yNiA4MiAtNjhjMCAtODYgLTEwNSAtMTY0IC0y%0AODQgLTE4N2MtMTAgLTIwIC0xMCAtNDYgLTEwIC02MWMwIC01NSAzNyAtOTEg%0AOTMgLTkxYzQ0IDAgNzUgMTYgMTQ3IDc1ek0xNTIgMjUybC0xNyAtNDRjODYg%0AMjEgMTI0IDM5IDE2MSA3NGMzMSAzMCA1MCA2NiA1MCA5NyBjMCAyNCAtNyAz%0AOSAtMzUgMzljLTU3IDAgLTEyNSAtNzcgLTE1OSAtMTY2WiI+PC9wYXRoPjxw%0AYXRoIGlkPSJTVElYV0VCTUFJTkktNzIiIHN0cm9rZS13aWR0aD0iMTAiIGQ9%0AIk0xNzYgMjIzbDE2IDM1YzE5IDQyIDUzIDk1IDk0IDEzOGMyNiAyNyA1NiA0%0ANSA3OSA0NWMyOCAwIDQ3IC0yMSA0NyAtNTFzLTE3IC01NCAtNDcgLTU0Yy0x%0AOCAwIC0yNiAxMSAtMzUgMjZjLTYgMTAgLTkgMTQgLTE2IDE0Yy0xOCAwIC00%0ANiAtMzMgLTgyIC05NGMtNDMgLTc0IC02MSAtMTE0IC0xMTEgLTI4MmgtNzZs%0AODEgMjkyYzE0IDUyIDE2IDYxIDE2IDgycy0xOCAyNiAtMzggMjZjLTggMCAt%0AMTYgLTEgLTMxIC0zdjE3bDE1NSAyN2wzIC0yIFoiPjwvcGF0aD48cGF0aCBp%0AZD0iU1RJWFdFQk1BSU4tNUYiIHN0cm9rZS13aWR0aD0iMTAiIGQ9Ik01MDAg%0ALTEyNWgtNTAwdjUwaDUwMHYtNTBaIj48L3BhdGg+PHBhdGggaWQ9IlNUSVhX%0ARUJNQUlOSS02OSIgc3Ryb2tlLXdpZHRoPSIxMCIgZD0iTTI2NCA1OTljMCAt%0AMjggLTIzIC01MSAtNDkgLTUxYy0yOSAwIC00OCAyMSAtNDggNTNjMCAzMSAy%0AMCA1MyA0NyA1M3M1MCAtMjYgNTAgLTU1ek0yMjIgMTE0bDEzIC0xMWMtNTUg%0ALTg0IC04NyAtMTE0IC0xMzcgLTExNGMtMzMgMCAtNDkgMTggLTQ5IDU1YzAg%0AMjAgNyA1NSAyMiAxMTFsNDggMTc3YzUgMTggOSAzNiA5IDQ0YzAgMjAgLTEw%0AIDIzIC02NCAyNHYxNmMzOSAzIDU5IDYgMTYwIDI1bDQgLTNsLTk0IC0zNDMg%0AYy01IC0xNyAtMTAgLTMwIC0xMCAtNDRjMCAtMTAgNiAtMTUgMTQgLTE1YzE3%0AIDAgNDEgMjEgODQgNzhaIj48L3BhdGg+PC9kZWZzPjxnIHN0cm9rZT0iYmxh%0AY2siIGZpbGw9ImJsYWNrIiBzdHJva2Utd2lkdGg9IjAiIHRyYW5zZm9ybT0i%0AbWF0cml4KDEgMCAwIC0xIDAgMCkiPjx1c2UgeGxpbms6aHJlZj0iI1NUSVhX%0ARUJNQUlOSS02MiI+PC91c2U+PHVzZSB4bGluazpocmVmPSIjU1RJWFdFQk1B%0ASU5JLTc0IiB4PSI1MDUiIHk9IjAiPjwvdXNlPjx1c2UgeGxpbms6aHJlZj0i%0AI1NUSVhXRUJNQUlOSS02RSIgeD0iODA2IiB5PSIwIj48L3VzZT48dXNlIHhs%0AaW5rOmhyZWY9IiNTVElYV0VCTUFJTi01RiIgeD0iMTMxMSIgeT0iMCI+PC91%0Ac2U+PHVzZSB4bGluazpocmVmPSIjU1RJWFdFQk1BSU5JLTcwIiB4PSIxODE2%0AIiB5PSIwIj48L3VzZT48dXNlIHhsaW5rOmhyZWY9IiNTVElYV0VCTUFJTkkt%0ANjUiIHg9IjIzMjUiIHk9IjAiPjwvdXNlPjx1c2UgeGxpbms6aHJlZj0iI1NU%0ASVhXRUJNQUlOSS03MiIgeD0iMjc3NCIgeT0iMCI+PC91c2U+PHVzZSB4bGlu%0AazpocmVmPSIjU1RJWFdFQk1BSU4tNUYiIHg9IjMxOTEiIHk9IjAiPjwvdXNl%0APjx1c2UgeGxpbms6aHJlZj0iI1NUSVhXRUJNQUlOSS02OSIgeD0iMzY5NiIg%0AeT0iMCI+PC91c2U+PC9nPjwvc3ZnPg==%0A" alt="btn\_per\_i">

La division (tout comme la multiplication) est un point sensible en Verilog. En effet, l’opérateur de division existe bien dans le langage et il se peut que cela simule parfaitement.

C’est lorsque arrivera l’étape de la synthèse que l’on risque d’avoir quelques surprises. Il est possible que certains logiciels de synthèse réussiront à faire quelque chose en un coup d’horloge, mais il est certain que cela se fera au prix de très mauvaises performances en matière de ressources utilisées et de fréquence d’horloge. Il est surtout probable que votre logiciel de synthèse jette l’éponge.

Pour réaliser cette division, nous allons donc en revenir aux fondamentaux appris au primaire et poser la division. Une division, c’est la recherche du quotient et du reste de l’équation suivante :

<img style="display: inline; max-height: 1em;" class="mathjax" src="data:image/svg+xml;base64,PHN2ZyB4bWxuczp4bGluaz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGlu%0AayIgdmlld0JveD0iLTMgLTcxMi4yNzc0ODkwMDI1NDEgMTgzNTAuNDQ0NDQ0%0ANDQ0NDQ1IDkyMy41NTQ5NzgwMDUwODE4IiBzdHlsZT0id2lkdGg6IDQyLjY1%0AMWV4OyBoZWlnaHQ6IDIuMTY5ZXg7IHZlcnRpY2FsLWFsaWduOiAtMC42MDJl%0AeDsgbWFyZ2luOiAxcHggMHB4OyBwb3NpdGlvbjogc3RhdGljOyIgeG1sbnM9%0AImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj48ZGVmcyBpZD0iTWF0aEph%0AeF9TVkdfZ2x5cGhzIj48cGF0aCBpZD0iU1RJWFdFQk1BSU5JLTQ0IiBzdHJv%0Aa2Utd2lkdGg9IjEwIiBkPSJNMTMxIDY1M2gyNzdjMTc1IDAgMjkyIC05NCAy%0AOTIgLTI2OWMwIC0xMjQgLTYyIC0yMjUgLTE2MCAtMzAxYy03MyAtNTcgLTE3%0ANCAtODMgLTI5MSAtODNoLTI1N3YxNmM1NiAxMCA2NiAxNyA4MiA3NmwxMjIg%0ANDQ1YzcgMjUgMTEgNDQgMTEgNTljMCAyNyAtMTUgMzkgLTc2IDQxdjE2ek0z%0AMTAgNTg0bC0xMTggLTQyMmMtMTcgLTYyIC0yMiAtODIgLTIyIC05NWMwIC0y%0ANiAyMiAtMzcgNjggLTM3YzEwMSAwIDE3OSAzMCAyNDEgOTAgYzcxIDY5IDEx%0AMCAxODcgMTEwIDI4OGMwIDgwIC0yOSAxNDMgLTc4IDE4MGMtMzEgMjMgLTcz%0AIDM1IC0xMzEgMzVjLTM4IDAgLTYwIC00IC03MCAtMzlaIj48L3BhdGg+PHBh%0AdGggaWQ9IlNUSVhXRUJNQUlOSS02OSIgc3Ryb2tlLXdpZHRoPSIxMCIgZD0i%0ATTI2NCA1OTljMCAtMjggLTIzIC01MSAtNDkgLTUxYy0yOSAwIC00OCAyMSAt%0ANDggNTNjMCAzMSAyMCA1MyA0NyA1M3M1MCAtMjYgNTAgLTU1ek0yMjIgMTE0%0AbDEzIC0xMWMtNTUgLTg0IC04NyAtMTE0IC0xMzcgLTExNGMtMzMgMCAtNDkg%0AMTggLTQ5IDU1YzAgMjAgNyA1NSAyMiAxMTFsNDggMTc3YzUgMTggOSAzNiA5%0AIDQ0YzAgMjAgLTEwIDIzIC02NCAyNHYxNmMzOSAzIDU5IDYgMTYwIDI1bDQg%0ALTNsLTk0IC0zNDMgYy01IC0xNyAtMTAgLTMwIC0xMCAtNDRjMCAtMTAgNiAt%0AMTUgMTQgLTE1YzE3IDAgNDEgMjEgODQgNzhaIj48L3BhdGg+PHBhdGggaWQ9%0AIlNUSVhXRUJNQUlOSS03NiIgc3Ryb2tlLXdpZHRoPSIxMCIgZD0iTTIwNyA3%0AMGwzMSAzMmM3MiA3NCAxMzcgMTg0IDEzNyAyMzFjMCAxMCAtNSAxNyAtMTgg%0AMjljLTE4IDE2IC0yNSAyOSAtMjUgNDVjMCAyMSAxNyAzNCAzOCAzNGMzMyAw%0AIDU2IC0zMiA1NiAtNTljMCAtNDMgLTI4IC0xMDEgLTYzIC0xNTVjLTQ1IC03%0AMCAtMTAxIC0xMzQgLTExOSAtMTUzYy01NSAtNTkgLTgyIC05MiAtOTkgLTky%0AYy02IDAgLTkgMTAgLTkgMjd2MjRjMCA2OSAtMTEgMjAyIC0yNCAyNzhzLTI0%0AIDkzIC02MSA5MyBjLTEwIDAgLTIwIDAgLTMxIC0xdjEzYzQ1IDcgODAgMTQg%0AMTEyIDIxYzggMyAxNSA0IDIwIDRjOSAwIDkgLTYgMzAgLTExNGMxMyAtNjcg%0AMTkgLTEyMiAyNSAtMjU3WiI+PC9wYXRoPjxwYXRoIGlkPSJTVElYV0VCTUFJ%0ATkktNjkiIHN0cm9rZS13aWR0aD0iMTAiIGQ9Ik0yNjQgNTk5YzAgLTI4IC0y%0AMyAtNTEgLTQ5IC01MWMtMjkgMCAtNDggMjEgLTQ4IDUzYzAgMzEgMjAgNTMg%0ANDcgNTNzNTAgLTI2IDUwIC01NXpNMjIyIDExNGwxMyAtMTFjLTU1IC04NCAt%0AODcgLTExNCAtMTM3IC0xMTRjLTMzIDAgLTQ5IDE4IC00OSA1NWMwIDIwIDcg%0ANTUgMjIgMTExbDQ4IDE3N2M1IDE4IDkgMzYgOSA0NGMwIDIwIC0xMCAyMyAt%0ANjQgMjR2MTZjMzkgMyA1OSA2IDE2MCAyNWw0IC0zbC05NCAtMzQzIGMtNSAt%0AMTcgLTEwIC0zMCAtMTAgLTQ0YzAgLTEwIDYgLTE1IDE0IC0xNWMxNyAwIDQx%0AIDIxIDg0IDc4WiI+PC9wYXRoPjxwYXRoIGlkPSJTVElYV0VCTUFJTkktNjQi%0AIHN0cm9rZS13aWR0aD0iMTAiIGQ9Ik01MjEgNjgzbDYgLTZsLTM5IC0xNTJs%0ALTYwIC0yMTljLTMxIC0xMTQgLTY1IC0yMzAgLTY1IC0yNDZjMCAtMTIgNSAt%0AMjAgMTggLTIwYzE3IDAgMjggOSA4MiA3MWwxMiAtMTBjLTQ5IC03MyAtOTcg%0ALTExNCAtMTQ3IC0xMTRjLTI2IDAgLTQxIDE4IC00MSA0NWMwIDIzIDIgMzkg%0AMTMgODljLTU5IC05OSAtMTEwIC0xMzIgLTE3OCAtMTMyYy02NSAwIC0xMDcg%0ANDEgLTEwNyAxMTdjMCAxNjIgMTYyIDMzNSAyOTIgMzM1IGM0MiAwIDU5IC0x%0AOSA2NSAtNThoMWw0NSAxNjNjMTUgNTMgMTQgNTcgMTQgNzFjMCAyMSAtOSAy%0ANCAtNjQgMjZ2MTdjNjQgNiAxMDAgMTIgMTUzIDIzek0zNTYgMzYxYzAgMzYg%0ALTI0IDU3IC00NyA1N2MtMjggMCAtNjMgLTE3IC05MSAtNDZjLTY2IC03MCAt%0AMTE2IC0xNzkgLTExNiAtMjYyYzAgLTQ2IDIzIC03MyA1OCAtNzNjOTIgMCAx%0AOTYgMTcyIDE5NiAzMjRaIj48L3BhdGg+PHBhdGggaWQ9IlNUSVhXRUJNQUlO%0ASS02NSIgc3Ryb2tlLXdpZHRoPSIxMCIgZD0iTTM1OCAxMDlsMTIgLTEyYy01%0ANyAtNzAgLTEyMSAtMTA4IC0yMDQgLTEwOGMtODEgMCAtMTM1IDU0IC0xMzUg%0AMTM3YzAgMTU1IDE0OSAzMTUgMjk5IDMxNWM1MyAwIDgyIC0yNiA4MiAtNjhj%0AMCAtODYgLTEwNSAtMTY0IC0yODQgLTE4N2MtMTAgLTIwIC0xMCAtNDYgLTEw%0AIC02MWMwIC01NSAzNyAtOTEgOTMgLTkxYzQ0IDAgNzUgMTYgMTQ3IDc1ek0x%0ANTIgMjUybC0xNyAtNDRjODYgMjEgMTI0IDM5IDE2MSA3NGMzMSAzMCA1MCA2%0ANiA1MCA5NyBjMCAyNCAtNyAzOSAtMzUgMzljLTU3IDAgLTEyNSAtNzcgLTE1%0AOSAtMTY2WiI+PC9wYXRoPjxwYXRoIGlkPSJTVElYV0VCTUFJTkktNkUiIHN0%0Acm9rZS13aWR0aD0iMTAiIGQ9Ik00NjAgMTE3bDE0IC0xM2MtNjggLTkzIC05%0AMyAtMTEzIC0xNDAgLTExM2MtMjUgMCAtNDcgMTYgLTQ3IDU0YzAgMTAgMiAy%0AMyAxNiA3NWw0NCAxNjJjOCAzMSAxNCA2NyAxNCA3OWMwIDE4IC05IDI5IC0y%0ANCAyOWMtNDAgMCAtODUgLTQ5IC0xNDggLTE0MmMtNDUgLTY3IC01MyAtOTAg%0ALTEwMCAtMjQ4aC03NWw5NiAzNTBjMSA1IDIgMTEgMiAxN2MwIDIwIC0xNCAy%0ANiAtNjUgMjd2MTZjODEgMTYgMTA5IDIwIDE2MiAzMWw0IC0ybC02NyAtMjE4%0AIGMxMDAgMTYwIDE2NyAyMjAgMjMxIDIyMGM0MyAwIDY1IC0yNSA2NSAtNjFj%0AMCAtMTggLTQgLTM5IC0xMCAtNjBsLTU2IC0yMDNjLTEwIC0zNiAtMTQgLTUz%0AIC0xNCAtNjFjMCAtOSA0IC0xOCAxNiAtMThjMTQgMCAzMiAxNiA2MSA1M2M3%0AIDggMTQgMTcgMjEgMjZaIj48L3BhdGg+PHBhdGggaWQ9IlNUSVhXRUJNQUlO%0ASS02NCIgc3Ryb2tlLXdpZHRoPSIxMCIgZD0iTTUyMSA2ODNsNiAtNmwtMzkg%0ALTE1MmwtNjAgLTIxOWMtMzEgLTExNCAtNjUgLTIzMCAtNjUgLTI0NmMwIC0x%0AMiA1IC0yMCAxOCAtMjBjMTcgMCAyOCA5IDgyIDcxbDEyIC0xMGMtNDkgLTcz%0AIC05NyAtMTE0IC0xNDcgLTExNGMtMjYgMCAtNDEgMTggLTQxIDQ1YzAgMjMg%0AMiAzOSAxMyA4OWMtNTkgLTk5IC0xMTAgLTEzMiAtMTc4IC0xMzJjLTY1IDAg%0ALTEwNyA0MSAtMTA3IDExN2MwIDE2MiAxNjIgMzM1IDI5MiAzMzUgYzQyIDAg%0ANTkgLTE5IDY1IC01OGgxbDQ1IDE2M2MxNSA1MyAxNCA1NyAxNCA3MWMwIDIx%0AIC05IDI0IC02NCAyNnYxN2M2NCA2IDEwMCAxMiAxNTMgMjN6TTM1NiAzNjFj%0AMCAzNiAtMjQgNTcgLTQ3IDU3Yy0yOCAwIC02MyAtMTcgLTkxIC00NmMtNjYg%0ALTcwIC0xMTYgLTE3OSAtMTE2IC0yNjJjMCAtNDYgMjMgLTczIDU4IC03M2M5%0AMiAwIDE5NiAxNzIgMTk2IDMyNFoiPjwvcGF0aD48cGF0aCBpZD0iU1RJWFdF%0AQk1BSU4tM0QiIHN0cm9rZS13aWR0aD0iMTAiIGQ9Ik02MzcgMzIwaC01ODl2%0ANjZoNTg5di02NnpNNjM3IDEyMGgtNTg5djY2aDU4OXYtNjZaIj48L3BhdGg+%0APHBhdGggaWQ9IlNUSVhXRUJNQUlOSS01MSIgc3Ryb2tlLXdpZHRoPSIxMCIg%0AZD0iTTY5IC0xNjlsLTEwIDE2Yzc3IDU0IDg2IDYxIDE3NyAxNDFjLTExNCAy%0AMyAtMTc2IDEwOCAtMTc2IDIzN2MwIDEyMyA2NCAyNTMgMTczIDM0N2M3NyA2%0ANSAxNjUgOTQgMjQxIDk0YzEzNyAwIDIyNSAtMTAyIDIyNSAtMjM3YzAgLTE1%0ANiAtMTA0IC0zMjIgLTI1NiAtNDAyYy01NCAtMjkgLTg5IC0zOCAtMTY0IC00%0AM2wtNTQgLTU3aDI1YzM0IDAgNzkgLTEwIDEyMyAtMjBjNDEgLTEwIDc4IC0y%0AMSAxMTEgLTIxYzcyIDAgMTEyIDE5IDE2OCA3NyBsMTYgLTExYy0xNSAtMjEg%0ALTMyIC00MSAtNTIgLTU5Yy01MCAtNDUgLTExNCAtNzUgLTE5MSAtNzVjLTM4%0AIDAgLTkxIDggLTE0OCAyNmMtNDMgMTQgLTczIDE4I

par martoni, Yves Bourguignon, Ysabeau, Davy Defaud, BAud, Xavier Teyssier, Benoît Sibaud, Frédéric Massot, palm123, Xavier Claude, bobble bubble, mzf

DLFP - Dépêches

LinuxFr.org

Trivabble, l’aventure continue

 -  19 octobre - 

Une nouvelle version de Trivabble, un jeu de Scrabble en réseau présenté ici‑même, vient de sortir. lien nᵒ 1 : Site Web de Trivabblelien nᵒ 2 : (...)


GIMP 2.10.22 : consolidation des formats

 -  18 octobre - 

GIMP 2.10.22 est sorti le 4 octobre dernier. Le cœur du logiciel ne connaît pas de bouleversements avec cette nouvelle version ; en revanche, cette (...)


Le Conseil d’État reconnaît que le gouvernement US peut accéder aux données de santé des Français

 -  15 octobre - 

Dans une ordonnance rendue publique ce jour, le Conseil d’État, saisi par le collectif Santenathon, reconnaît que le gouvernement des États‑Unis (...)


Pitivi 1.0 (en fait : 2020.09) est sorti, après 16 ans de développement !

 -  14 octobre - 

Pitivi, logiciel de montage vidéo pour GNOME, basé sur GStreamer, et qui se veut simple et puissant, est enfin sorti, le 30 septembre 2020, dans sa (...)


Gestion des plans de tests, intégration continue, nouvelle UI : version majeure Tuleap 12

 -  24 septembre - 

Pour Tuleap ce mois de septembre 2020 est signe de nouveautés : l’équipe de Tuleap est heureuse de vous annoncer la sortie de la version majeure (...)