vovike 0 10 сентября, 2016 Опубликовано 10 сентября, 2016 · Жалоба Всем привет! Есть 9 бит дробной части двоичного числа Нужно получить 3 десятичных знака для последующего вывода на 7 сегментный индикатор Подскажите, может есть какой то хитрый приём как это реализовать? Для целой части понравился вариант как на картинке, а для дробной что-то не нашёл Verilog HDL, Altera MAX II EPM240 Спасибо за ответы по существу Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Maverick_ 15 10 сентября, 2016 Опубликовано 10 сентября, 2016 · Жалоба Всем привет! Есть 9 бит дробной части двоичного числа Нужно получить 3 десятичных знака для последующего вывода на 7 сегментный индикатор Подскажите, может есть какой то хитрый приём как это реализовать? Для целой части понравился вариант как на картинке, а для дробной что-то не нашёл Verilog HDL, Altera MAX II EPM240 Спасибо за ответы по существу BCD все равно что преобразовывать, поставьте какой-то конвертор перед подачей данных на BCD для дробной части для коректного преобразования Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
gosu-art 0 12 сентября, 2016 Опубликовано 12 сентября, 2016 · Жалоба // [b]Binary to BCD converter - Shift and Add-3 Algorithm[/b] always_comb begin thousands = 0; hundreds = 0; tens = 0; ones = 0; empty = 0; for(j=15;j>=0;j--)begin if(thousands >=5) thousands = thousands + 3; if(hundreds >=5) hundreds = hundreds + 3; if(tens >=5) tens = tens + 3; if(ones >=5) ones = ones + 3; if(empty >=5) empty = empty + 3; thousands = thousands << 1; thousands[0] = hundreds[3]; hundreds = hundreds << 1; hundreds[0] = tens[3]; tens = tens << 1; tens[0] = ones[3]; ones = ones << 1; ones[0] = empty[3]; empty = empty << 1; empty[0] = data_in[j]; end data[0] = thousands; data[1] = hundreds; data[2] = tens; data[3] = ones; end Опробовал лично - все работает Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vovike 0 12 сентября, 2016 Опубликовано 12 сентября, 2016 · Жалоба Нет Проверьте для двоичного числа 0.101000000 (0,625 десятичное) например. Что на выходе? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Serhiy_UA 1 12 сентября, 2016 Опубликовано 12 сентября, 2016 · Жалоба Подскажите, может есть какой то хитрый приём как это реализовать? Для целой части понравился вариант как на картинке, а для дробной что-то не нашёл Если целую часть Вы знаете как перевести, то для дроби можно поступить следующим образом.. Дробь умножить на десятичную 100 (сотню), а в двоичной коде эта сотня будет 1100100. Так как умножителя на этой ПЛИС нет, но надо выполнить три суммирования с соответствующими сдвигами (т.к. есть три единицы в двоичном представлении сотни). Полученное число будет уже целое, и его уже легче преобразовать в BCD. Если сотни будет мало, то возьмите тысячу. Только там есть пять единиц подряд 1111101000, Тогда вместо 5-и идущих подряд сложений выполнить одно сложение и одно вычитание, т.к. 1111101000 = (10000001000 - 0000100000).... Уточняю, для трех слагаемых два сумматора, т.е. на один меньше. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vovike 0 12 сентября, 2016 Опубликовано 12 сентября, 2016 · Жалоба Спасибо! Гениально! Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
OM-S 0 12 сентября, 2016 Опубликовано 12 сентября, 2016 · Жалоба я как то делал компонент перевода дробной части в BCD. Кажется алгоритм основан на Shift and Add 3. Сейчас уже не помню. Вот код LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_ARITH.ALL; USE IEEE.Math_real.ALL; ENTITY tr3_bin2bcd_frac IS GENERIC( InputWidth : integer := 16; OutputDigits : integer := 16 ); PORT( clk : IN STD_LOGIC; d : IN std_logic_vector (InputWidth-1 DOWNTO 0); q : OUT std_logic_vector (4*OutputDigits-1 DOWNTO 0); q_we : OUT STD_LOGIC; nrst : IN std_logic; int_ready : IN std_logic := '1'; frac_ready : BUFFER std_logic ); -- Declarations END tr3_bin2bcd_frac; architecture Behavioral of tr3_bin2bcd_frac is constant NumberOfDigits: integer := OutputDigits; --constant NumberOfDigits: integer := integer(Ceil(real(InputWidth) * 0.30103)); --constant NeededOutputWidth: integer := NumberOfDigits * 4; type TCorrectTable is array(0 to 15) of std_logic_vector(3 downto 0); constant Correct8_sub3: TCorrectTable := (x"0", x"1", x"2", x"3", x"4", x"5", x"6", x"7", x"5", x"6", x"7", x"8", x"9", x"A", "----", "----" -- max input = 13(dec) ); signal dBuf: std_logic_vector(InputWidth-1 downto 0); -- буфер аргумента signal qBuf: std_logic_vector(4*OutputDigits-1 downto 0); -- буфер результата type TState is (Buffering, Shifting); signal State, LastState: TState; signal ShiftCounter: integer range 0 to InputWidth-1; signal first_flag : boolean := true; begin process(clk, nrst) variable tmpBuf_v : std_logic_vector(qBuf'left downto 0); begin if nrst = '0' then dBuf <= (others => '0'); qBuf <= (others => '0'); ShiftCounter <= 0; State <= Buffering; q <= (others => '0'); q_we <= '0'; first_flag <= true; frac_ready <= '0'; elsif rising_edge(clk) then -- default value q_we <= '0'; LastState <= State; -- fsm case State is when Buffering => if LastState /= Buffering then q <= qBuf; q_we <= '1' and int_ready; end if; frac_ready <= '1'; dBuf <= d; qBuf <= (others => '0'); ShiftCounter <= InputWidth-1; if (dBuf /= d or first_flag) and (int_ready = '1' and frac_ready = '1') then first_flag <= false; State <= Shifting; frac_ready <= '0'; end if; when Shifting => tmpBuf_v := dBuf(0) & qBuf(qBuf'left downto 1); for i in NumberOfDigits downto 1 loop qBuf(i*4-1 downto i*4-4) <= Correct8_sub3(CONV_INTEGER(unsigned(tmpBuf_v(i*4-1 downto i*4-4)))); end loop; dBuf <= dBuf(0) & dBuf(InputWidth-1 downto 1); if ShiftCounter = 0 then State <= Buffering; frac_ready <= '1'; else ShiftCounter <= ShiftCounter - 1; end if; when others => State <= Buffering; end case; end if; end process; end Behavioral; Все должно работать. Вход int_ready можно не использовать и подать на него 1. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
nand_gates 0 20 сентября, 2016 Опубликовано 20 сентября, 2016 · Жалоба Check this out! :laughing: module bin2bcd(/*AUTOARG*/ // Outputs S, // Inputs A ); input [3:0] A; output [3:0] S; reg [3:0] S; always @(A) case(A)//synopsys parallel_case 0 : S=0; 1 : S=1; 2 : S=2; 3 : S=3; 4 : S=4; 5 : S=8; 6 : S=9; 7 : S=10; 8 : S=11; 9 : S=12; default : S=4'bxxxx; endcase endmodule // bin2bcd module Binary_to_BCD_8(P,B); output [9:0] P; //BCD form of B input [7:0] B; wire [3:0] co1, co2, co3, co4; wire [2:0] co6; assign P[0]= B[0]; bin2bcd C1(.A({1'b0,B[7:5]}), .S(co1)); bin2bcd C2(.A({co1[2:0],B[4]}), .S(co2)); bin2bcd C3(.A({co2[2:0],B[3]}), .S(co3)); bin2bcd C4(.A({co3[2:0],B[2]}), .S(co4)); bin2bcd C5(.A({co4[2:0],B[1]}), .S(P[4:1])); bin2bcd C6(.A({1'b0,co1[3],co2[3],co3[3]}), .S({P[9],co6})); bin2bcd C7(.A({co6,co4[3]}), .S(P[8:5])); endmodule // Binary_to_BCD_8 module test(); reg [7:0] B; wire [9:0] P; // End of automatics Binary_to_BCD_8 Binary_to_BCD_8(/*AUTOINST*/ // Outputs .P (P[9:0]), // Inputs .B (B[7:0])); initial begin $monitor($time,,"Bin=%0x BCD = %0x",B,P); B=0; repeat(256) #10 B=B+1; $finish; end endmodule // test Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться