lexx 0 June 24, 2008 Posted June 24, 2008 · Report post К вечеру башка совсем не работает, как проще реализовать следующую вещь (Verilog): reg [7:0] A, B, C, D; d = (A - 4*B + 4*C - D) / 8 ("/" - dicivion by trancation toward zero) d1 = |d| Все то что на ум приходит необходимо отслеживать на переполнение, а это слишком большим получается. Забыл сказать, исходные числа только положительны Quote Share this post Link to post Share on other sites More sharing options...
iosifk 3 June 24, 2008 Posted June 24, 2008 · Report post К вечеру башка совсем не работает, как проще реализовать следующую вещь (Verilog): reg [7:0] A, B, C, D; d = (A - 4*B + 4*C - D) / 8 ("/" - dicivion by trancation toward zero) d1 = |d| Все то что на ум приходит необходимо отслеживать на переполнение, а это слишком большим получается. Забыл сказать, исходные числа только положительны Заменить умножение и деление чисел, кратных 2, сдвигом влево-вправо на соответствующее число разрядов и все дела. ну а абс значение определяется по старшему разряду. Если это отрицательное число, то делается преобразование. Эта операция зависит от формы представления числа... Quote Share this post Link to post Share on other sites More sharing options...
lexx 0 June 24, 2008 Posted June 24, 2008 · Report post Сдвиги это понятно (можно б было об этом и не упоминать) wire [10:0] A_addC, B_addD; wire [11:0] sum; wire [8:0] sum_dev; wire [7:0] abs_sum_dev; assign A_sumC = A + (C << 2'b10); assign B_sumD = (B << 2'b10 + D); assign sum = {1'b0, A_sumC} - {1'b0, B_sumD}; assign sum_dev = sum >> 2'b11; assign abs_sum_dev = sum_dev[8] ? (!sum_dev + 1'b1) : sum_dev; Вроде все так, или нет так или еще проще есть вариант? Остается вопрос почему на работе до этого не доходишь, элементарно же ведь Quote Share this post Link to post Share on other sites More sharing options...
sazh 11 June 24, 2008 Posted June 24, 2008 · Report post Сдвиги это понятно (можно б было об этом и не упоминать) Отнюдь ( input [7:0] a, b, c, d, output [8:0] abs_sum_dev ); wire [8:0] A_add_D; wire [10:0] B_add_C; wire [11:0] sum; wire [8:0] sum_dev; assign A_add_D = a - d; assign B_add_C = {c, 2'b00} - {b, 2'b00}; assign sum = {2'b00, A_add_D} + B_add_C; assign sum_dev = sum[11:3]; assign abs_sum_dev = sum_dev[8] ? -sum_dev : sum_dev; Quote Share this post Link to post Share on other sites More sharing options...
lexx 0 June 25, 2008 Posted June 25, 2008 · Report post Еще вопросик: a = (2*(p5 - p8) - 5*(p6 - p7) + 4) >>3 Сейчас это выглядит следующим образом (входы строго положительны): input [7:0] P5, P6, P7, P8; wire [8:0] P5Sub8, P6Sub7; wire [10:0] A2Temp1; wire [11:0] A2Temp2, A2Temp; wire [8:0] A2Combo; assing P5Sub8 = {1'b0, P5} - {1'b0, P8}; assing P6Sub7 = {1'b0, P6} - {1'b0, P7}; assign A2Temp1 = {P5Sub8[8], P5Sub8, 1'b0} + 11'd4; assign A2Temp2 = {P6Sub7[8], P6Sub7, 2'b00} + {P6Sub7[8], P6Sub7[8], P6Sub7[8], P6Sub7}; assign A2Temp = {A2Temp1[10], A2Temp1} - A2Temp2; assign A2Combo = A2Temp[11:3]; Но немного не хватает по performance, есть идеи? Quote Share this post Link to post Share on other sites More sharing options...
sazh 11 June 25, 2008 Posted June 25, 2008 · Report post Но немного не хватает по performance, есть идеи? какие идеи. непонятки одни. С представлением чисел. Или пользуйтесь ключевыми словами signed? unsigned. Или вручную. Но не смешивайте понятия. module sum_signed_unsigned ( input add, input [3:0] a, b, // unsigned input [3:0] aa, bb, // signed output [4:0] s, // unsigned output [4:0] ss // signed ); assign s = add ? {1'b0, a} + {1'b0, b} : {1'b0, a} - {1'b0, b}; assign ss = add ? {aa[3], aa} + {bb[3], bb} : {aa[3], aa} - {bb[3], bb}; endmodule Quote Share this post Link to post Share on other sites More sharing options...
CaPpuCcino 0 June 25, 2008 Posted June 25, 2008 · Report post Еще вопросик: a = (2*(p5 - p8) - 5*(p6 - p7) + 4) >>3 ребят, а зачем вам вообще заморочки с ручным упрощением? нормальный синтезёр по-моему разложит это по оптимальной схеме автоматически (?) Quote Share this post Link to post Share on other sites More sharing options...
sazh 11 June 25, 2008 Posted June 25, 2008 · Report post ребят, а зачем вам вообще заморочки с ручным упрощением? нормальный синтезёр по-моему разложит это по оптимальной схеме автоматически (?) а что значит нормальный синтезатор. Разложит без расширения разрядной сетки. А кому это надо. Quote Share this post Link to post Share on other sites More sharing options...
CaPpuCcino 0 June 25, 2008 Posted June 25, 2008 · Report post а что значит нормальный синтезатор. Разложит без расширения разрядной сетки. А кому это надо. а отдать эту заботу на попечение встроенных типов int или unsigned int? при синтезе лишние биты будут сокращены (?) Quote Share this post Link to post Share on other sites More sharing options...
sazh 11 June 25, 2008 Posted June 25, 2008 · Report post а отдать эту заботу на попечение встроенных типов int или unsigned int? при синтезе лишние биты будут сокращены (?) Я ведь из народа вышел. Приведите выше описанное с int. Буду благодарен. Quote Share this post Link to post Share on other sites More sharing options...
lexx 0 June 26, 2008 Posted June 26, 2008 · Report post ребят, а зачем вам вообще заморочки с ручным упрощением? нормальный синтезёр по-моему разложит это по оптимальной схеме автоматически (?) Не хватет синтезатора, либо ломать то что уже сделано (увеличивать число клоков на расчет, и следовательно падает performance), либо переписывать логику на более простую. Quote Share this post Link to post Share on other sites More sharing options...
lexx 0 October 13, 2008 Posted October 13, 2008 · Report post Возвращаясь к начальному, посколько тогда это было не использовано, но теперь понадобилось. d = (A - 4*B + 4*C - D) / 8 ("/" - dicivion by trancation toward zero) собака порылась в последнем, как поделить с насыщеним к нулю, если цифра отрицательна? 5 - 0101 (-5) - 1011 5/2 = 2 - 010 (-5/2) = -2 - 110 Но если просто сдвинуть на 1 бит (-5), то будет 101, т.е. неверно. Можно конечно выйти в положительную плоскость, но это приведет к двойному суммированию (туда и обратно). Есть вариант: + x[3] (старший бит сдвигаемого числа) и только потом сдвигать, но всегда ли он верен? Quote Share this post Link to post Share on other sites More sharing options...
des00 27 October 13, 2008 Posted October 13, 2008 · Report post d = (A - 4*B + 4*C - D) / 8 ("/" - dicivion by trancation toward zero) вообще то классика жанра, во всех книгах по быстрой арифметике есть. если число отрицательное и отбрасываемый остаток != 0 то + 1. вот для деления на 4 always_comb begin if (dat2scale[$high(dat2scale)] & dat2scale[1:0] != 0) dat4scale = dat2scale[$high(dat2scale):2] + 1'b1; else dat4scale = dat2scale[$high(dat2scale):2]; end Удачи Quote Share this post Link to post Share on other sites More sharing options...
lexx 0 October 13, 2008 Posted October 13, 2008 · Report post вообще то классика жанра, во всех книгах по быстрой арифметике есть. если число отрицательное и отбрасываемый остаток != 0 то + 1. вот для деления на 4 always_comb begin if (dat2scale[$high(dat2scale)] & dat2scale[1:0] != 0) dat4scale = dat2scale[$high(dat2scale):2] + 1'b1; else dat4scale = dat2scale[$high(dat2scale):2]; end Удачи Спасибо, в принципе то что я написал выше совпадает с вашим, можно просто сложить со старшим битом числа в количестве равном сдвигу. Получается, что если остаток ненулевой, то +1, либо +3, либо +7, что немного меньше, поскольку нет сравнения. :beer: А книжки нет под руками, :wassat: Спасибо, в принципе то что я написал выше совпадает с вашим, можно просто сложить со старшим битом числа в количестве равном сдвигу. Получается, что если остаток ненулевой, то +1, либо +3, либо +7, что немного меньше, поскольку нет сравнения. :beer: Обшибся, у вас сумматор на пару бит меньше получается, ваш проще. А книжки нет под руками, :wassat: Quote Share this post Link to post Share on other sites More sharing options...
AlexBT_ 0 October 4, 2011 Posted October 4, 2011 · Report post Подскажите, пожалуйста, как реализовать в Verilog'95 нижеприведенную схему? Quote Share this post Link to post Share on other sites More sharing options...