Skip to Content

TimeQuest для чайников. Приложение 2 (Хак для System Synchronus Ouput на cycloneIII)

module time_test (input clk1, clk2, clk3,
                  input [7 : 0] data1, data2, data3,
                  input [1 : 0] sel,
                  output logic [7 : 0] odat,
                  output               oclk
                  ) ;

  logic [7 : 0] data1_reg [0 : 1], data2_reg [0 : 1] , data3_reg[0 : 1]  ;

  always_ff @(posedge clk1) begin
    {data1_reg[1], data1_reg[0]} <= {data1_reg[0], data1};
  end

  always_ff @(posedge clk2) begin
    {data2_reg[1], data2_reg[0]} <= {data2_reg[0], data2};
  end

  always_ff @(posedge clk3) begin
    {data3_reg[1], data3_reg[0]} <= {data3_reg[0], data3};
  end

  logic [7 : 0] mux_data, mux_data_reg;
  logic         mux_clk ;

  always_comb begin
    unique case(sel)
      2'b01   : {mux_clk, mux_data} = {clk2, data2_reg[1]};
      2'b10   : {mux_clk, mux_data} = {clk3, data3_reg[1]};
      default : {mux_clk, mux_data} = {clk1, data1_reg[1]};
    endcase
  end

  always_ff @(posedge mux_clk) begin
    mux_data_reg <= mux_data;
  end

  //
  // output mapping
 
  logic [7 : 0] data2hi, data2lo ;
  logic         clk2hi,  clk2lo  ;
 
  assign data2hi = mux_data_reg;
  assign data2lo = mux_data_reg;

  generate
    genvar i;
    for (i = 0; i < 8; i++) begin : data_gen
      ddio_out
      ddio_out
      (
        .aclr     ( 1'b0        ) ,
        .datain_h ( data2hi [i] ) ,
        .datain_l ( data2lo [i] ) ,
        .outclock ( mux_clk     ) ,
        .dataout  ( odat    [i] )
      );
    end
  endgenerate 
 
  assign clk2hi = 1'b0;  // inverted
  assign clk2lo = 1'b1;  

  ddio_out
  ddio_out
  (
    .aclr     ( 1'b0    ),
    .datain_h ( clk2hi  ),
    .datain_l ( clk2lo  ),
    .outclock ( mux_clk ),
    .dataout  ( oclk    )
  );

endmodule

Но собрав и запустив анализ я увидел странные данные. На один и тот же путь было 2 ре времянки, что по началу ввело меня в ступор. Вот первый путь

Вот второй

Причем как видите основной нужный нам констрейн не выполняется.

Но ларчик просто открывался, видя что данные меняются по обоим фронтам клока, TimeQuest находит 2 ре времянки для tsu/th. Он то не знает что нас интересует конкретная ситуация с восходящего фронта до восходящего фронта. А квартус в свою очередь стремиться при разводке выполнить условия по обоим фронтам LaunchClock, именно поэтому констрейны, по нужным нам фронтам не выполняются.  Чтобы ему это объяснить используем наш старый знакомый set_false_path.


Комментарии

Отправить комментарий

Содержание этого поля является приватным и не предназначено к показу.
  • Адреса страниц и электронной почты автоматически преобразуются в ссылки.
  • Использовать как разделитель страниц.
  • Syntax highlight code surrounded by the {syntaxhighlighter OPTIONS}...{/syntaxhighlighter} tags.

Подробнее о форматировании