Pour convertir une donnée venant en 2x 1x à horloge dans Verilog ou SystemVerilog

voix
1

Je travaille sur la validation. I face courante un problème de convertir un ensemble de données qui arrive à une unité d'horloge dans 2x.

Pour un signal de bits de 132 se déplace comme 66 bus de bits dans 2x horloge.

A la réception de nouveau toute la conversion de l'horloge doit être fait de 2x à 1x reprendre les 132 bits du signal.

Quelqu'un peut-il me aider sur la façon de le faire?

Merci beaucoup d'avance.

Créé 12/04/2011 à 14:45
source utilisateur
Dans d'autres langues...                            


3 réponses

voix
1

Puisque la question est étiquetée veriloget system-verilogje suppose un module Verilog pour effectuer la conversion est souhaitée.

En supposant que les horloges d'entrée et de sortie sont synchrones, voici le code (pas bien testé, peut nécessiter quelques modifications):

module conv_2x_to_1x (rst, clk_in, data_in, clk_out, data_out);

parameter IN_WIDTH = 66;
input wire rst, clk_in, clk_out;
input wire [IN_WIDTH-1:0] data_in;
output reg [2*IN_WIDTH-1:0] data_out;

localparam LOWER_HALF = 0, UPPER_HALF = 1;
reg [2*IN_WIDTH-1:0] data_tmp;
reg half;

always @(posedge clk_in or posedge rst)
  if (rst) begin
    data_tmp <= {2*IN_WIDTH {1'b0}};
    half <= LOWER_HALF;
  end else if (half == LOWER_HALF) begin
    data_tmp [IN_WIDTH-1:0] <= data_in;
    half <= UPPER_HALF;
  end else begin
    data_tmp [2*IN_WIDTH-1:IN_WIDTH] <= data_in;
    half <= LOWER_HALF;
  end

always @(posedge clk_out or posedge rst)
  data_out <= rst ? {2*IN_WIDTH {1'b0}} : data_tmp;

endmodule

Je l'ai testé cela avec ce stimulus:

module test;

reg rst;
reg [1:0] clk;
reg [65:0] data_in;
wire [131:0] data_out;

conv_2x_to_1x conv_2x_to_1x (rst, clk[0], data_in, clk[1], data_out);

always #5 clk = clk + 2'b01;

initial begin
  $monitor ("%3t: %1b, %2b, %66h, %66h %66h", $time, rst, clk, data_in,
            data_out [131:66], data_out [65:0]);
  clk = 2'b00;
  #2 rst = 1'b1;
  @ (negedge clk [0]) #2 begin
    rst = 1'b0;
    data_in = 66'h2d_eadbe_efcaf_ebabe;
  end
  @ (negedge clk [0]) #2 data_in = 66'h1b_adc0f_fedea_dc0de;
  @ (negedge clk [0]) #2 data_in = 66'h3c_afeba_bedea_dbeef;
  @ (negedge clk [0]) #2 data_in = 66'h0d_eadc0_debad_c0ffe;
  #12 $finish;
end

endmodule

Si les horloges d'entrée et de sortie ne sont pas synchrones, je pense que vous aurez besoin pour passer un signal de drapeau dans le domaine d'horloge d'entrée qui doit être double synchronisés à l'horloge domaine de sortie et transmis à la logique de sortie. Lorsque la logique côté de sortie détecte le basculement, il peut lire data_outet devra définir un autre signal d'indicateur qui doit être à double synchronisés et transmis à la logique du côté d'entrée. Jusqu'à ce que la logique d'entrée voit cette deuxième bascule du drapeau , je pense qu'il ne devrait pas changer data_in.

Créé 23/05/2013 à 11:48
source utilisateur

voix
1

Voici un excellent article sur les techniques de passage de domaine d'horloge.

Créé 12/04/2011 à 16:25
source utilisateur

voix
1

La manière habituelle est que vous avez un double registre 132 bits porté. Avec un port dans votre domaine d'horloge 1x et l'autre port dans votre domaine d'horloge de 2x. Comme on est en lecture seule et une écriture seule, vous pouvez simplement le décrire comme un registre normal. Mais la migration entre les différents domaines d'horloge est très délicat, esp. en raison de métastabilité. Ne contourner cela, vous devez ajouter un autre niveau (s) des bascules (c.-à-un autre registre).

Ma réponse est pas très précis et détaillé, mais cela est dû au fait, que votre question est très non spécifique / large.

Créé 12/04/2011 à 14:58
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more