![]() |
|
|
|
#1 |
|
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 <= (OTHERS => '0'); elsif shift_en_s = '1' then bcd_out_s <= bcd_out_modified_s(22 downto 0) & ser_out_s; end if; end if; ... bcd_out_modified_s(3 downto 0) <= bcd_out_s(3 downto 0) + "0011" when bcd_value(3 downto 0) >= "0101" else bcd_value(3 downto 0); ... or: if clk = '1' and clk'event then if load_data = '1' then bcd_out_s <= (OTHERS => '0'); elsif shift_en_s = '1' then bcd_value := bcd_out_s; if bcd_value(3 downto 0) >= "0101" then bcd_value(3 downto 0) := bcd_value(3 downto 0) + "0011"; end if; ... bcd_out_s <= bcd_value(22 downto 0) & ser_out_s; end if; end if; I'm sure there are other ways to structure the code, and my way may add an additional clock cycle or may need an extra bit in the register to work right, but you get the idea. (2) Process #3 makes use of an asynchronous clear on the condition of load_data. If you can do something synchronously instead of asynchronously, you should. There's no harm in putting another if clause in your clocked portion of the process to cover the clear while loading case. (3) Process #2. You have two if statements, both of which affect bin_in_s: if load_data = '1' then bin_in_s <= data_in; end if; if shift_en_s = '1' then bin_in_s <= bin_in_s(18 downto 0) & '0'; end if; While legal, the interpretation (I think) is the same as the following code, which is cleaner and thus less likely to be incorrect. My experience is whenever I try to be as smart as the compiler, I end up getting bitten by it later... if shift_en_s = '1' then bin_in_s <= bin_in_s(18 downto 0) & '0'; elsif load_data = '1' then bin_in_s <= data_in; end if; (4) Process #1 & #4. You are instantiating many more registers than necessary. You could get away without the data_out register (unless you want to be able to process new data while some other chip takes its time reading your result, which seems unlikely). Also, you are inserting an extra cycle of latency with your data_ready & data_out registers. But there should be nothing functionally wrong there. (5) Your asynchronous reset may not be safe. The topic of many discussions. Not the problem you're having now I bet. Good luck, Paul Leventis Paul Leventis |
|
|
|
|
#2 |
|
Posts: n/a
|
Paul Leventis wrote:
> Hi Jason, > > First off, that's a pretty cool little algorithm... had to prove to myself > that it worked. ... > > I'm not sure that I've found the problem with your code, ... 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. > (0) I think the first problem is a lack of comments... uncommented code is > always wrong 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. > (1) Process #3. I hate variables. Especially variables mixed with > signals... Signals are the only way in and out of a process. > 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. 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 Mike Treseler |
|
|
|
#3 |
|
Posts: n/a
|
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 longer at Fairchild (but it was an interesting 10 years) ==================== Mike Treseler wrote: > > Paul Leventis wrote: > > Hi Jason, > > > > First off, that's a pretty cool little algorithm... had to prove to myself > > that it worked. ... > > > > I'm not sure that I've found the problem with your code, ... > > 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. > > > (0) I think the first problem is a lack of comments... uncommented code is > > always wrong > > 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. > > > (1) Process #3. I hate variables. Especially variables mixed with > > signals... > > Signals are the only way in and out of a process. > > > 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. > > 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 Peter Alfke |
|
|
|
#4 |
|
Junior Member
Join Date: Mar 2008
Posts: 1
|
[quote=Peter Alfke]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 longer at Fairchild (but it was an interesting 10 years) ==================== I know this is an old thread but I was searching for ways to do serial binary to BCD and found this. I just happened to have a copy of the Fairchild TTL Applications Handbook so thought I'd attach a copy of the circuits. One converts to BCD parallel output and the other converts to serial BCD output. Serial Binary to Parallel BCD.jpg Serial Binary to Serial BCD.jpg crutschow |
|
|
|
|
|
#5 |
|
Senior Member
Join Date: Mar 2008
Location: Denmark
Posts: 245
|
This old hardware been reinvented several times
http://www.jjmk.dk/MMMI/Lessons/06_A...sion/Index.htm Your welcome Jeppe jeppe |
|
|
|
![]() |
| Thread Tools | Search this Thread |
|
|
Similar Threads
|
||||
| Thread | Thread Starter | Forum | Replies | Last Post |
| image (jpg,bmp,gif, etc.) convert to equivalent binary representation using vb.net? | archieSupremo | Software | 0 | 09-06-2009 12:20 PM |
| reading mp3 file in binary format in vhdl | latheesh | General Help Related Topics | 0 | 02-05-2008 05:40 AM |
| How to activate Remote Assistance with XP using Windows Live Messenger | Oziisr | General Help Related Topics | 0 | 02-01-2008 04:45 PM |
| Not For Profit Assistance Provided By American Consultants Rx | nxkq20nv | DVD Video | 0 | 11-15-2007 01:47 AM |
| Counting In Binary | Raymond | A+ Certification | 13 | 03-07-2004 07:28 PM |