Re: binary to BCD assistance

Hello, I have attached a portion of code for a binary to bcd counter, 20

> bits parallel input, and a 24 bit BCD output parallel. Although internally > it converts it to serial to go through the conversion. I'm attempting the > shift and add three (if greater than or equal to 5) method, but I am

having

some problems. It works great on the simulator (Aldec Active HDL) and I

can

synthesize it but when I put it on the chip I'm getting some odd things. I > am using 16 input toggle switches and i debounced pb switch as a load > switch, and my outputs are LEDs. When I set this up on the board my

outputs

go as follows:

The attachment didn't come through. Can you just include some of the code in the body, instead of an attachment?

-- glen

Reply to
Glen Herrmannsfeldt
Loading thread data ...

internally

the

I

OK, it did come through but I was looking in the wrong place. Still, it is often easier just to include it.

I am much better at reading verilog than VHDL, but it doesn't look right to me. Though I think I don't understand the algorithm, I think it needs to be more complicated than that, though if you do an iterative algorithm it might not be so hard. How many clock cycles does it take to get the data from input to output? How many different values did you put through the simulator in testing?

-- glen

Reply to
Glen Herrmannsfeldt

sure

The

Start

greater

representation.

As I said, I read Verilog much better than VHDL. I didn't even notice the loop yesterday, which is why I didn't think it was complicated enough. OK, thought for today:

(snip)

Does the following generate a gated clock?

The following statement must be done before the rest. While simulators may execute them in order, synthesized logic tends to execute them all at the same time.

(snip)

Gated clocks are especially hard in FPGA's.

-- glen

Reply to
Glen Herrmannsfeldt

Hi Jason,

First off, that's a pretty cool little algorithm... had to prove to myself that it worked. Let digit = 5 + n, where n = 0..4. We want new_digit = (digit * 2 + shift_in) % 10 = (5 * 2 + n * 2 + shift_in) % 10 = n * 2 + shift_in. If we add three, and wrap around at 16 (since 4-bit representation) then we get ((8 + n) * 2 + shift_in) % 16 = 2 * n + shift_in.

I'm not sure that I've found the problem with your code, but there were a number of stylistic issues and one suspicious fragment I figured I'd point out. I'll add a caveat that I haven't really coded up any VHDL in a year or so, and prior to that my experience was mostly with structural VHDL. And I didn't have a compiler handy to try out my ideas. So I imagine I'll find out I'm wrong and learn something in the process!

(0) I think the first problem is a lack of comments... uncommented code is always wrong :-)

(1) Process #3. I hate variables. Especially variables mixed with signals... you must be very disciplined when using variables (I only use them in for loops...). So I honestly don't know what the code will translate into, as you are assigning a value to variable, then assigning to the variable to a signal, then changing the value of the variable. I'm not sure if the scheduled signal assignment occurs before or after the change in variable value. Also, I'm not sure that the variable turns into a register (i.e. has memory) -- either way though, it's not what you want. If it does become a register, then have 2 24-bit registers (unnecsessary/may not work). If you don't, then I don't know what will happen. Regardless, I think you want to first be adding three, THEN shifting. There are two ways I can think of restructuring this code into something that may work (see below). The first replaces your variable with a signal that is computed combinationally outside of the process. The second is an attempt to still use a variable, based on my limited understanding of this VHDL construct. Note that neither requires the asynchronous condition (though I'm thinking it may need an aclr for bcd_out_s...).

if clk = '1' and clk'event then if load_data = '1' then bcd_out_s '0'); elsif shift_en_s = '1' then bcd_out_s

Reply to
Paul Leventis

Not if it follows the line

elsif rising_edge(clk) then

in a synchronous process.

It's the process template that gives you a synchronous clock, not any single sequential statement.

This synthesizes nothing unless bcd_value is assigned directly or indirectly to an entity port.

If this assignment occurs within a synchronous process, the output will be registered by clk.

If you stick to the synchronous process template, you will never have one to worry about.

-- Mike Treseler

Reply to
Mike Treseler

The best and quickest way to do both is to write a testbench an run a sim. This quickly resolves all questions about how the langage works and how the logic functions.

My favorite comments are a plain text description at the top of each process about function and handshake protocols. These can be collected at the top of the architecture after the sim is working.

Detail comments at the end of line, can often be replaced by by well-named statement labels, constants and variables.

Signals are the only way in and out of a process.

In the case referenced, the first value is exported to the signal at the next clk and the second value is held by the variable until the next clk, if it is needed.

This is not as complex as you think. Variables are stuck inside the process. They only reach the entity ports if you make a signal assignment inside the process. Synthesis will use a register to save the variable's *final* value. only if this value is needed at the next clk.

Run a sim sometime, and watch the variables as you trace code.

-- Mike Treseler

Reply to
Mike Treseler

Here is a time-proven hardware design for bit-serial binary to parallel BCD conversion. (I published this in 1973 in the Fairchild TTL Applications Handbook).

Implement a bunch of 4-bit loadable shift register, but do not interconnect them. For each shift register drive a 4-bit adder (without carry in, but with carry output) from the 4 shift register outputs. Put a binary eleven (B) as other input on the adder. Connect the adder outputs to the shift register load inputs, but skewed one position downstream ( bit 0 of the adder drives bit 1 of the shift register ). Then use the carry output as load enable for "its" shift register, and also as input for the LSB of the downstream shift register ( both as shift- and as load- input) The S3 output ( most significant sum) goes nowhere. That's it.

Shifting in binary data (MSB first) doubles the binary value on every shift. The adder monitors this and, on its carry output, signals that there is a value 5 or larger, which needs intervention: add 3 before the next shift ( which is equivalent to adding 6 after having shifted it) and load a carry into the next higher bit position. The neat trick is that the 4-bit adder simultaneously adds eleven to create a carry that detects the need for modification, and also adds three to do the modification.

Shift in binary data, MSB first, and watch the BCD develop on the parallel shift register outputs. Note that BCD needs more bit positions than binary, so leave some headroom. Works like a champ, flawlessly since 30 years ago.

Peter Alfke, no l>

if

value.

Reply to
Peter Alfke

Hi Jason, I found your algorithm in C (see source after the vhdl code) on the net. It's cool. I rewrited your code like this (see bellow) and it works fine (I tested): (bin and bcd width (20 and 24) could be replaced by constants (C_BIN_WIDTH, C_BCD_WIDTH)). Hope this will help.

library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all;

entity bin2bcd is port( i_clk : in std_logic; i_rst_an : in std_logic; i_load_data : in std_logic; i_data : in std_logic_vector(20-1 downto 0);

o_data_rdy_q : out std_logic; o_data_q : out std_logic_vector(24-1 downto 0) ); end bin2bcd;

architecture rtl of bin2bcd is begin --------------------------------------------------------------------------

--
  -- register mapping:
  --
  -- ------------------------
  -- |    v_bcd_bin_q       |
  -- ------------------------
  -- |  av_bcd_q   |        |
  -- ------------------------
  -- |         |  av_bin_q  |
  -- ------------------------
  --           |xxx| 3 bits overlaps to save 3 clk cycle processing and 3
dff
  --
  --------------------------------------------------------------------------
Reply to
FE

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.