The adder is working as it should but the subtractor isn't and I can't really see what the problem is since I've checked the expression and it is correct, but when I simulate it seems like the subtraction part isn't working at all...
Firs, in bitAdder the process sensitivity list is missing b_sub, which will have an event one delta cycle after b. You could end up operating on the last b_sub value, which also has an inferred latch should you want to synthesize this (b_sub is not assigned under else).
To accomplish subtraction by adding the two's complement of the top level b you need a + 1 accomplished by carry in. To preserve the ability to use your top level cin, you can simply invert the value of cin being delivered to cell_0 when add_sub = '0'. This allows you to chain operations of WIDTH width operands.
I made the above changes and your design did not produce any assertion violations. (As long as you don't let it run long enough for the process with the assertion statements to wrap, it should be terminated by say wait 49 ns; wait;. The extra wait so you can display waveforms more or less uniformly for all tests.)
This example describes a two input parameterized adder/subtractor design in VHDL. The design unit multiplexes add and subtract operations with an addnsub input. Synthesis tools detect add and subtract units in HDL code that share inputs and whose outputs are multiplexed by a common signal. Software infers lpm_addsub megafunction for such add/subtract designs.
The 1 bit full adder works perfectly.
The 4 bit adder/subtracter, built up from the 1 bit full adder, works perfectly.
The final, 8 bit adder/subtractor, is where my problem lies and I have beat my head against the wall until the dents are now noticeable (in both my head AND the wall).
The 'fix' has GOT to be simple but it sure hasn't popped into my head...and I've tried so many iterations to resolve it I've lost track of what I've done and haven't done!
I'm pretty certain the problem lies in how the COUT and CIN values are being passed from the 1st 4 bit adder/subtractor iteration to the 2nd...but danged if I can figure out what I've done wrong!
CIN = 0 for addition (the B inputs don't get inverted and the CIN value of 0 adds nothing to the circuit's final value)
CIN = 1 for subtraction ( the B inputs get inverted, 1's complement, and the CIN value of 1 makes it 2's complement)
From there each COUT is then wired up to the CIN of the next 1bit full adder.
As I said in my original post...the 4 bit ripple carry adder/subtractor circuit is working fine. It's when I instantiate 2 of them, in the 8 bit adder/subtractor, that I'm running into my problem. If I build an 8 bit adder/subtractor out of 8 instantiated 1 bit full adders...that ALSO works fine.
Being overly optimistic or dependent on automated tools is a dangerous way to live. Even if the tools are doing their job correctly there are so many ways to subvert its purpose. There is simply no substitute for using that grey matter that uses so much of the energy that your body produces. Of course training those neural networks to perform well takes time and practice. But it's essential to have the skill to do competent design and verification. Formal verification methods certainly have their place but they are not a substitute for learning how to analyse logic issues.
Even seasoned engineers create code that appears to work on first blush but has hidden issues ready to torpedo your efforts. This is why all HDL code needs a testbench. And, as you get more hours of experience finding corner cases of failure your testbenches will get better at finding them early rather than later.
Many years ago I was implementing an FEC by re-writing Fortran simulation code into DSP assembly code. The customer was willing to pay for verification so all modules had a software 'testbench'. (The software development process and digital logic development process is very similar in many regards). Anyway, part of the Reed-Solomon design appeared to me to need exhaustive testing so instead of relying on finding errors with a simple software testbench I designed a test to run on hardware. The test rig ran for hours without an error and then all a sudden I started getting an error or cluster of errors but at really low rates. It took a few days thinking about the few errors that I found to come up with a plausible explanation which pointed me to a sometimes used bit of Fortran where there was a simple logic error, probably a typo or cut and paste error. The guy who wrote the Fortran algorithms had done proper testing and not found the error. I had done proper testing in software and not found the error but throwing massive amounts of data at the code in hardware did. Finding the error using software would likely have taken days or weeks of computer simulation.
Sometimes you can anticipate the 'usual suspects' and sometimes you can't. Sometimes your automated tools will find issues that they are designed to find and sometimes your problem isn't one of them. And sometimes, even very smart people do dumb things and reach some bad conclusions. The truth is that debugging, whatever it is that you are testing, involves debugging the analysis and thinking of the person running the show. Don't try to take yourself out of the verification process because you are part of the failure both in terms of design and verification.
I should point out that rarely do people write HDL modules that are supposed to do all things for every possible application, at every possible clock rate, etc, etc, etc. We write modules that have limitations and restrictions and are meant to accomplish a limited functionality. This isn't an error. Being unaware of those restrictions, limitations and details that haven't been addressed in the code is an error. Not documenting those restrictions, limitations and details is a very costly error.
It's definitely still not right and the 2 changes you've suggested don't fix the problem. Take a look at the attached waveform. I have it starting at 89,919,000 ns. If you follow along with the A, B and CIN inputs...you'll see problems even here....WAY before the problems I identified at A=0xB0 and B=0x00
However, to be sure I wasn't missing ANY of your changes I pasted your entire version into the design. Once I realized you had "IfDef"s surrounding your necessary changes I realized they'd do no harm in the Verilog design. However I DID have to comment out this line; `default_nettype none
So I ran it again and perused the wave form panel in detail. Strangely enough the design works all the way thru a[7:0]=0xB) and b[7:0] = 0x0.
Beyond that point...the addition's are correct but the subtractions are incorrect.
This has been what I've been doing for the past 2 days...trying zillion's of 'ideas'/iterations to resolve the issue but I just can't seem to find one.
Your solution definitely is the closest the design has come to fully working.
Ok, I think I found your bug. Your carry bits are messed up. In the case of the 4-bit, you want to XOR the operation (not cin) with the carry to get the four bit add/subtract to pass. That will then properly subtract two 4-bit numbers, but it will also leave the carry wrong for the 8-bit adder. To make the 8-bit add/sub work, you'll need to invert carry[1] at the 8b level as well..
Can you tell me how the 4-bit subtract is supposed to work? Specifically, what is the carry supposed to do? Are you trying to calculate (A-B-carry), or (A-B+carry), or ... I'm not sure. I'm currently looking at A=8, B=0, and seeing some results I don't get either.
1. Waveform output: I have the output starting at a[7:0] input = A0. You can see the B[7:0] input increasing from 0 to 1 to 2 to 3.....etc. You can further see the CIN value changing from 0 to 1 for each of the A and B input values.
2. TCL console output: I have this printed output starting at a[7:0] input = A0 so you can match the various values up to the waveform output. The columns of data in the TCL output are:
[TIME] [A Input]. [B Input]. [S output]. [COUT output]. [CIN input].
This example describes a two input 4-bit adder/subtractor design in VHDL. The design unit multiplexes add and subtract operations with an OP input. 0 input produce adder output and 1 input produce subtractor output.
Hi thanks for the example.
Quick question: why is line 39 included as I was under the impression that C4/Cout was already classed as the overflow, so why include it at all and include C3 as an overflow ??
About Us
Invent Logics is the manufacturers of high-quality and low-cost EDGE FPGA development Boards. EDGE FPGA kits are the feature-rich development board with the best documentation support. We aim to offer the best FPGA learning platform to students, research scholars, and young engineers.
Simple as Possible (SAP) computers in general were designed to introduce beginners to some of the crucial ideas behind computer operations. SAP computers are classified into stages, each stage more evolved and considering more advanced concepts in computer architecture than the previous.
The SAP-1 computer is the first stage in this evolution and contains the basic necessities for a functional computer. Its primary purpose is to develop a basic understanding of how a computer works, interacts with memory and other parts of the system like input and output. The instruction set is very limited and is simple.
In this project, I together with a group of people implement a SAP-1 computer using an FPGA (Field Programmable Gate Array) - an integrated circuit designed to be configured by a customer or a designer after manufacturing - and the FPGA programmed using VHDL (VHSIC-HDL, Very High Speed Integrated Circuit Hardware Description Language).
The SAP-1 computer is a bus-organized computer and makes use of Von-Neumann architecture. It makes use of an 8-bit central bus and has ten main components. A pictorial representation of its architecture is shown below. Each of the individual components that make up this computer are described right after.
b1e95dc632