Перейти к содержанию
    

вопрос по verilog коду

Добрый день.

 

Интересует следующий вопрос.

Вот есть код, сгенерируемый симулинком из модели.Это просто Cordic ядро для вычисления синуса.

 

`timescale 1 ns / 1 ns

module Sine
         (
          clk,
          reset_n,
          enb,
          u,
          sin_2_pi_u
         );


 input   clk;
 input   reset_n;
 input   enb;
 input   [15:0] u;  // ufix16_En19
 output  signed [15:0] sin_2_pi_u;  // sfix16_En14


 reg [15:0] u_1;  // ufix16_En19
 wire [15:0] CastU16En16_out1;  // ufix16_En16
 wire LTEp50_relop1;
 wire [15:0] Amp50_out1;  // ufix16_En16
 wire [15:0] QuadHandle1_out1;  // ufix16_En16 
 wire LTEp25_relop1;
 wire [15:0] p50mA_out1;  // ufix16_En16
 wire [15:0] QuadHandle2_out1;  // ufix16_En16
 reg signed [15:0] Look_Up_Table_out1;  // sfix16_En14
 wire signed [16:0] Negate_cast;  // sfix17_En14
 wire signed [15:0] Negate_out1;  // sfix16_En14
 wire signed [15:0] SignCorrected_out1;  // sfix16_En14
 reg signed [15:0] Sine_out1;  // sfix16_En14 
 reg signed [15:0] Look_Up_Table_dout_low_1;  // sfix16_En14
 reg [5:0] Look_Up_Table_k_1;  // ufix6
 reg [31:0] Look_Up_Table_f_1;  // ufix32_En31
 reg signed [15:0] Look_Up_Table_t_0_0_1 [0:32];  // sfix16_En14 [33]
 reg [15:0] Look_Up_Table_div_temp_1;  // ufix16
 reg [46:0] Look_Up_Table_div_temp_0_1;  // ufix47_En31
 reg [15:0] Look_Up_Table_cast_1;  // ufix16_En16
 reg [31:0] Look_Up_Table_mul_temp_1;  // ufix32_En32
 reg [15:0] Look_Up_Table_sub_temp_1;  // ufix16_En16
 reg signed [48:0] Look_Up_Table_add_cast_2;  // sfix49_En45
 reg signed [32:0] Look_Up_Table_cast_0_1;  // sfix33_En31
 reg signed [15:0] Look_Up_Table_sub_temp_0_1;  // sfix16_En14
 reg signed [48:0] Look_Up_Table_mul_temp_0_1;  // sfix49_En45
 reg signed [47:0] Look_Up_Table_add_cast_0_1;  // sfix48_En45
 reg signed [48:0] Look_Up_Table_add_cast_1_1;  // sfix49_En45
 reg signed [48:0] Look_Up_Table_add_temp_1;  // sfix49_En45


 always @(posedge clk)
   begin : in_0_pipe_process
     if (reset_n == 1'b0) begin
       u_1 <= 16'b0000000000000000;
     end
     else if (enb) begin
       u_1 <= u;
     end
   end



 // <S7>/CastU16En16
 assign CastU16En16_out1 = u_1[15:3];



 // <S7>/LTEp50
 assign LTEp50_relop1 = (CastU16En16_out1 <= 16'b1000000000000000 ? 1'b1 :
             1'b0);



 // <S7>/Amp50
 assign Amp50_out1 = CastU16En16_out1 - 32768;



 // <S7>/QuadHandle1
 assign QuadHandle1_out1 = (LTEp50_relop1 == 1'b0 ? Amp50_out1 :
             CastU16En16_out1);



 // <S7>/LTEp25
 assign LTEp25_relop1 = (QuadHandle1_out1 <= 16'b0100000000000000 ? 1'b1 :
             1'b0);



 // <S7>/p50mA
 assign p50mA_out1 = 32768 - QuadHandle1_out1;



 // <S7>/QuadHandle2
 assign QuadHandle2_out1 = (LTEp25_relop1 == 1'b0 ? p50mA_out1 :
             QuadHandle1_out1);



 // <S6>/Look-Up Table
 always @(QuadHandle2_out1) begin
   Look_Up_Table_t_0_0_1[0] = 16'sb0000000000000000;
   Look_Up_Table_t_0_0_1[1] = 16'sb0000001100100100;
   Look_Up_Table_t_0_0_1[2] = 16'sb0000011001000110;
   Look_Up_Table_t_0_0_1[3] = 16'sb0000100101100100;
   Look_Up_Table_t_0_0_1[4] = 16'sb0000110001111100;
   Look_Up_Table_t_0_0_1[5] = 16'sb0000111110001101;
   Look_Up_Table_t_0_0_1[6] = 16'sb0001001010010100;
   Look_Up_Table_t_0_0_1[7] = 16'sb0001010110010000;
   Look_Up_Table_t_0_0_1[8] = 16'sb0001100001111110;
   Look_Up_Table_t_0_0_1[9] = 16'sb0001101101011101;
   Look_Up_Table_t_0_0_1[10] = 16'sb0001111000101011;
   Look_Up_Table_t_0_0_1[11] = 16'sb0010000011100111;
   Look_Up_Table_t_0_0_1[12] = 16'sb0010001110001110;
   Look_Up_Table_t_0_0_1[13] = 16'sb0010011000100000;
   Look_Up_Table_t_0_0_1[14] = 16'sb0010100010011010;
   Look_Up_Table_t_0_0_1[15] = 16'sb0010101011111011;
   Look_Up_Table_t_0_0_1[16] = 16'sb0010110101000001;
   Look_Up_Table_t_0_0_1[17] = 16'sb0010111101101100;
   Look_Up_Table_t_0_0_1[18] = 16'sb0011000101111001;
   Look_Up_Table_t_0_0_1[19] = 16'sb0011001101101000;
   Look_Up_Table_t_0_0_1[20] = 16'sb0011010100110111;
   Look_Up_Table_t_0_0_1[21] = 16'sb0011011011100101;
   Look_Up_Table_t_0_0_1[22] = 16'sb0011100001110001;
   Look_Up_Table_t_0_0_1[23] = 16'sb0011100111011011;
   Look_Up_Table_t_0_0_1[24] = 16'sb0011101100100001;
   Look_Up_Table_t_0_0_1[25] = 16'sb0011110001000010;
   Look_Up_Table_t_0_0_1[26] = 16'sb0011110100111111;
   Look_Up_Table_t_0_0_1[27] = 16'sb0011111000010101;
   Look_Up_Table_t_0_0_1[28] = 16'sb0011111011000101;
   Look_Up_Table_t_0_0_1[29] = 16'sb0011111101001111;
   Look_Up_Table_t_0_0_1[30] = 16'sb0011111110110001;
   Look_Up_Table_t_0_0_1[31] = 16'sb0011111111101100;
   Look_Up_Table_t_0_0_1[32] = 16'sb0100000000000000;
   if (QuadHandle2_out1 <= 16'b0000000000000000) begin
     Look_Up_Table_k_1 = 6'b000000;
   end
   else if (QuadHandle2_out1 >= 16'b0100000000000000) begin
     Look_Up_Table_k_1 = 6'b100000;
   end
   else begin
     Look_Up_Table_div_temp_1 = QuadHandle2_out1 / 512;
     Look_Up_Table_k_1 = Look_Up_Table_div_temp_1[5:0];
   end
   if ((QuadHandle2_out1 <= 16'b0000000000000000) || (QuadHandle2_out1 >= 16'b0100000000000000)) begin
     Look_Up_Table_f_1 = 32'b00000000000000000000000000000000;
   end
   else begin
     Look_Up_Table_cast_1 = 16'b0000000000000000;
     // CSD Encoding (512) : 1000000000; Cost (Adders) = 0
     Look_Up_Table_mul_temp_1 = {Look_Up_Table_cast_1, 9'b000000000};
     Look_Up_Table_sub_temp_1 = QuadHandle2_out1 - Look_Up_Table_mul_temp_1[31:16];
     Look_Up_Table_div_temp_0_1 = ({Look_Up_Table_sub_temp_1, 31'b0000000000000000000000000000000}) / 512;
     Look_Up_Table_f_1 = Look_Up_Table_div_temp_0_1[31:0];
   end
   Look_Up_Table_dout_low_1 = Look_Up_Table_t_0_0_1[Look_Up_Table_k_1];
   if (Look_Up_Table_k_1 == 6'b100000) begin
   end
   else begin
     Look_Up_Table_k_1 = Look_Up_Table_k_1 + 1;
   end
   Look_Up_Table_add_cast_2 = {{2{Look_Up_Table_dout_low_1[15]}}, {Look_Up_Table_dout_low_1, 31'b0000000000000000000000000000000}};
   Look_Up_Table_cast_0_1 = Look_Up_Table_f_1;
   Look_Up_Table_sub_temp_0_1 = Look_Up_Table_t_0_0_1[Look_Up_Table_k_1] - Look_Up_Table_dout_low_1;
   Look_Up_Table_mul_temp_0_1 = Look_Up_Table_cast_0_1 * Look_Up_Table_sub_temp_0_1;
   Look_Up_Table_add_cast_0_1 = Look_Up_Table_mul_temp_0_1[47:0];
   Look_Up_Table_add_cast_1_1 = {Look_Up_Table_add_cast_0_1[47], Look_Up_Table_add_cast_0_1};
   Look_Up_Table_add_temp_1 = Look_Up_Table_add_cast_2 + Look_Up_Table_add_cast_1_1;
   Look_Up_Table_out1 = Look_Up_Table_add_temp_1[46:31];
 end



 // <S7>/Negate
 assign Negate_cast =  - ({Look_Up_Table_out1[15], Look_Up_Table_out1});
 assign Negate_out1 = Negate_cast[15:0];



 // <S7>/SignCorrected
 assign SignCorrected_out1 = (LTEp50_relop1 == 1'b0 ? Negate_out1 :
             Look_Up_Table_out1);



 always @(posedge clk)
   begin : out_0_pipe_process
     if (reset_n == 1'b0) begin
       Sine_out1 <= 16'sb0000000000000000;
     end
     else if (enb) begin
       Sine_out1 <= SignCorrected_out1;
     end
   end



 assign sin_2_pi_u = Sine_out1;

endmodule  // Sine

 

Я тут вижу 2 регистра, входной - по которому защелкиваются данные и выходной, по которому посчитанные данные защелкиваются.

Между ними идет какая-то асинхронщина. Меня смущает вот эта строчка always @(QuadHandle2_out1) . Причем там есть еще счетчик - т.е. по идее это должен быть регистр-защелка для счетчика.

Причем синтезатор показывает, что код может работать на частоте в почти 84 МГц. И защелок в проекте нет вообще. Хотя все-таки остается ощущение, что если будут всякие температурные скачки, то возможно появление метастабильного состояния выходного регистра.

Можно ли использовать данный код в проекте?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

if (Look_Up_Table_k_1 == 6'b100000) begin
end
else begin
Look_Up_Table_k_1 = Look_Up_Table_k_1 + 1;
end

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

if (Look_Up_Table_k_1 == 6'b100000) begin
end
else begin
Look_Up_Table_k_1 = Look_Up_Table_k_1 + 1;
end

 

Это не счетчик, а временная переменная.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

 

Ну как же - вот же он!

always @(posedge clk) begin : in_0_pipe_process
    if (reset_n == 1'b0) begin
        u_1 <= 16'b0000000000000000;
    end
    else if (enb) begin
        u_1 <= u;
    end
end

из него выгрызают кусок

assign CastU16En16_out1 = u_1[15:3];

а затем легким движением рук

assign LTEp50_relop1 = (CastU16En16_out1 <= 16'b1000000000000000 ? 1'b1 :1'b0);

и бедер

assign assign assign Amp50_out1 = CastU16En16_out1 - 32768;
assign QuadHandle1_out1 = (LTEp50_relop1 == 1'b0 ? Amp50_out1 :CastU16En16_out1);

шорты превращаются в элегантный счетчик :wacko: :cranky: :)

 

Работать будет - но я бы за такой код убил бы.

 

Увы - это проблема всех кодогенераторов - формальная конверсия логики высокоуровневых языков в железо.

 

 

Успехов! Rob.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ого, даже так!

 

а где почитать про временные переменные?

что-то я с таким сталкиваюсь впервые

 

вообщем получается что код работать будет, но нестабильно?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Приветствую!

 

Ну почему же нестабильно - если задать правильные constrain для PR то все будет нормально.

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

 

Успехов! Rob.

 

P.S. Жуя обеденный бутерброд и искоса посматривая на это чудо код понял что это

не Cordic а похоже вычислительный блок - генерирующий sin от входного аргумента при помощи какойто мате... апроксимации.

Так что тут счетчика и не должно было быть.

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

что-то я не понял как тут счетчик образовался...

вернее как движения рук и бедер перевели входной регистр защелки в счетчик.

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...