Update
parent
ecd9c2f991
commit
96776982b7
@ -0,0 +1,36 @@
|
||||
# Git
|
||||
|
||||
Git (name without any actual meaning) is a [FOSS](foss.md) ([GPL](gpl.md)) [version control system](vcs.md) (system for maintaining and collaboratively developing [source code](source_code.md) of programs), currently the most mainstream-popular one (surveys saying over 90% developers use it over other systems). Git is basically a [command line](cli.md) program allowing to submit and track changes of text files (usually source code in some [programming language](programming_language.md)), offering the possibility to switch between versions, [branches](fork.md), detect and resolve conflicts in collaborative editing etc.
|
||||
|
||||
Git was created by [Linus Torvalds](linus_torvalds.md) in 2005 to host the development of [Linux](linux.md) and to improve on systems such as [svn](svn.md). Since then it has become extremely popular, mainly thanks to [GitHub](github.md), a website that offered hosting of git projects along with "social network" features for the developers; after this similar hosting sites such as [GitLab](gitlab.md) and [Codeberg](codeberg.md) appeared, skyrocketing the popularity of git even more.
|
||||
|
||||
It is generally considered quite a good software, many praise its distributed nature, ability to work offline etc., however diehard software idealists still criticize its mildly [bloated](bloat.md) nature and also its usage complexity -- it is non-trivial to learn to work with git and many errors are infamously being resolved in a "trial/error + google" style, so some still try to improve on it by creating new systems.
|
||||
|
||||
**Is git literally [hitler](hitler.md)?** Well, by [suckless](suckless.md) standards git IS bloated and yes, git IS complicated as fuck, however let's try to go deeper and ask the important questions, namely "does this matter so much?" and "should I use git or avoid it like the devil?". The answer is actually this: it doesn't matter too much that git is bloated and you don't have to avoid using it. Why? Well, git is basically just a way of hosting, spreading and mirroring your source onto many git-hosting servers (i.e. you can't avoid using git if you want to spread your code to e.g. Codeberg and GitLab) AND at the same time git doesn't create a [dependency](dependency.md) for your project, i.e. its shittiness doesn't "infect" your project -- if git dies or if you simply want to start using something else, you just copy-paste your source code elsewhere, you put it on [FTP](ftp.md) or anything else, no problem. It's similar to how e.g. [Anarch](anarch.md) uses [SDL](sdl.md) (which is bloated as hell) to run on specific platforms -- if it doesn't hard-depend on SDL and doesn't get tied to it, it's OK (and actually unavoidable) to make use of it. You also don't even have to get into the complicated stuff about git (like merging branches and resolving conflicts) when you're simply committing to a simple one-man project.
|
||||
|
||||
**Which git hosting to use?** All of them (except for [GitHub](github.md) which is a proprietary terrorist site)! Do not fall into the trap of [githopping](githopping.md), just make tons of accounts, one on each git hosting site, add multiple push remotes and just keep pushing to all of them -- EZ. Remember, git hosting sites are just free file storage servers, not social platforms or brands to identify with. Do not use their non-git "features" such as issue trackers, CI and shit. They want you to use them as "facebook for programmers" and become dependent on their exclusive "features", so that's exactly what you want to avoid, just abuse their platform for free file storage.
|
||||
|
||||
## Alternatives
|
||||
|
||||
Here are some alternatives to git:
|
||||
|
||||
- **nothing**: If you don't have many people on the project, you can comfortably just use nothing, like in good [old](old.md) times. Share a directory with the source code and keep regular backups in separate directories, share the source online via [FTP](ftp.md) or something like that.
|
||||
- **[svn](svn.md)**: The "main", older alternative to git, used e.g. by [SourceForge](sourceforge.md), apparently suffers from some design issues.
|
||||
- **[mailing list](mailing_list.md)**: Development happens over email, people just keep sending [patches](patch.md) that are review and potentially merged by the maintainers to the main code base. This is how [Linux](linux.md) was developed before git.
|
||||
- **[darcs](darcs.md)**: Alternative to git, written in [Haskell](haskell.md), advertising itself as simpler.
|
||||
- **[lit](lit.md)** (previously known as *gut*): WIP [LRS](lrs.md)/[suckless](suckless.md) version control system.
|
||||
- ...
|
||||
|
||||
## How To Use Git For Solo/Small Projects (Cheatsheet)
|
||||
|
||||
TODO
|
||||
|
||||
- `git add files_you_changed; git commit -m "Update"; git push`
|
||||
- `git pull`
|
||||
- `git stash`
|
||||
- `git rm file_to_remove`
|
||||
- `git init`
|
||||
- `git log`
|
||||
- `git diff`
|
||||
- `git apply diff_file`
|
||||
- *weird error*: just look it up on stack overflow
|
@ -1,27 +1,150 @@
|
||||
# Logic Circuit
|
||||
|
||||
Logic circuits are circuits made of [logic gates](logic_gate.md) that implement [Boolean functions](bool.md), i.e. they are "schematics to process 1s and 0s". They are used to design [computers](computer.md). Logic circuits are a bit similar to electronic circuits but are a level of [abstraction](abstraction.md) higher: they don't work with continuous [voltages](voltage.md) but rather with [discrete](discrete.md) [binary](binary.md) logic values: 1s and 0s. Logical circuits can be designed and simulated with specialized software and languages such as [VHDL](vhdl.md).
|
||||
Logic circuits are circuits made of [logic gates](logic_gate.md) that implement [Boolean functions](bool.md), i.e. they are "schematics to process 1s and 0s". They are used to design [computers](computer.md) on a low level. Logic circuits are a bit similar to electronic circuits but are a level of [abstraction](abstraction.md) higher: they don't work with continuous [voltages](voltage.md) but rather with [discrete](discrete.md) [binary](binary.md) logic values: 1s and 0s. This allows us to make kind of "[portable](portable.md)" circuit descriptions independent of any specific [transistor](transistor.md) technology, or even of [electronics](electronics.md) itself (as logical circuit may in theory be realized even mechanically or in other similarly wild ways). Logical circuits can be designed and simulated with specialized software and languages such as [VHDL](vhdl.md).
|
||||
|
||||
Generally a logic circuit has *N* input bits and *M* output bits. Then we divide logic circuits into two main categories:
|
||||
TODO: picture here
|
||||
|
||||
- **combinational**: The output values only depend on the input values, i.e. the circuit implements a pure mathematical [function](function.md). Behavior of such circuit can be described with a [truth table](truth_table.md), i.e. a table that for any combination of input values list their corresponding output.
|
||||
- **sequential**: The output values generally depend on the input values and the internal state of the circuit, i.e. the circuit has a kind of [memory](memory.md) (it can be seen as a [finite state machine](finite_state_machine.md)). The internal state is normally implemented with so called [flip-flops](flip_flop.md) (logic gates that take as input their own output). Truth tables can't be used for describing these circuits. These circuits also often work with **[clock](clock.md)** synchronization, i.e. they have a specialized input called *clock* that periodically switches between 1 and 0 which drives the circuit's operation (this is where [overclocking](overclocking.md) comes from).
|
||||
Generally a logic circuit can be seen as a "black box" that has *N* input bits and *M* output [bits](bit.md). Then we divide logic circuits into two main categories:
|
||||
|
||||
With logic circuits it is possible to implement any boolean function; [undecidability](undecidability.md) doesn't apply here as we're not dealing with [Turing machines](turing_machine.md) computations because the output always has a finite, fixed width, the computation can't end up in an infinite loop as there are no repeating steps, just a straightforward propagation of input values to the output. It is always possible to implement any function at least as a [look up table](lut.md) (which can be created with a [multiplexer](multiplexer.md)).
|
||||
- **combinational**: The output values only depend on the input values, i.e. the circuit implements a pure mathematical [function](function.md). Behavior of such circuit can be described with a [truth table](truth_table.md), i.e. a table that for any combination of input values list their corresponding output. Examples of combinational circuits may be the very basic of logic circuits, the [AND](and.md) and [OR](or.md) functions.
|
||||
- **sequential**: Extension of the former, here the output values generally depend on the input values AND additionally also on the internal [state](state.md) of the circuit, i.e. the circuit has a kind of [memory](memory.md) (it can be seen as a [finite state machine](finite_state_machine.md)). The internal state is normally implemented with so called [flip-flops](flip_flop.md) (logic gates that take as input their own output). Normal truth tables can't be used for describing these circuits (only if we include the internal state in them). These circuits also often work with **[clock](clock.md)** synchronization, i.e. they have a specialized input called *clock* that periodically switches between 1 and 0 which drives the circuit's operation (this is where [overclocking](overclocking.md) comes from).
|
||||
|
||||
Once we've designed a logic circuit, we can [optimize](optimization.md) it which usually means making it use fewer logic gates, i.e. make it cheaper to manufacture (but optimization can also aim for other things, e.g. shortening the maximum length from input to output, i.e. minimizing the circuit's [delay](delay.md)). The optimization can be done with a number of techniques such as manual simplification of the circuit's logic expression or with [Karnaugh maps](karnaugh_map.md).
|
||||
Logical circuits can be drawn simply as "boxes", which one the base level are the basic logic gates such as [AND](and.md), [OR](or.md) etc., connected with lines. But as mentioned, their behavior can also be described with a truth table or a boolean expression, i.e. an algebraic expression that for each of the circuit outputs defines how it is computed from the outputs, for example *o = (x AND y) OR z* where *o* is the output and *x*, *y* and *z* are the inputs (each of which can have a value of either 1 or 0). Each of these types of representation has its potential advantages -- for example the graphical representation is a very human-friendly representation while the algebraic specification allows for optimization of the circuits using algebraic methods. Many hardware design languages therefore allow to use and combine different methods of describing logic circuits (some even offer more options such as describing the circuit behavior in a programming language such as [C](c.md)).
|
||||
|
||||
Some common logic circuits include:
|
||||
With combinational logic circuits it is possible to implement any boolean function (i.e. "functions only with values 1 and 0"); [undecidability](undecidability.md) doesn't apply here as we're not dealing with [Turing machines](turing_machine.md) computations because the output always has a finite, fixed number of bits, the computation can't end up in an infinite loop as there are no repeating steps, just a straightforward propagation of input values to the output. It is always possible to implement any function at least as a [look up table](lut.md) (which can be created with a [multiplexer](multiplexer.md)). Sequential logic circuits on the other hand can be used to make the traditional computers that work in steps and can therefore get stuck in loop and so on.
|
||||
|
||||
Once we've designed a logic circuit, we can [optimize](optimization.md) it which usually means making it use fewer logic gates, i.e. make it cheaper to manufacture (but optimization can also aim for other things, e.g. shortening the maximum length from input to output, i.e. minimizing the circuit's [delay](delay.md)).
|
||||
|
||||
Some common logic circuits include (note that many of these can be implemented both as a combinational or sequential circuit):
|
||||
|
||||
- **[adder](adder.md)**: Performs addition. It has many parameters such as the bit width, optional carry output etc.
|
||||
- **[multiplier](multiplier.md)**: Performs multiplication.
|
||||
- **[multiplexer](multiplexer.md)** (mux): Has *M* address input bits plus another *2^M* data input bits. The output of the gate is the value of *N*th data bit where *N* is the number specified by the address input. I.e. the circuit selects one of its inputs and sends it to the output. This can be used to implement e.g. [memory](memory.md), [look up tables](lut.md), [bus](bus.md) arbiters and many more things.
|
||||
- **[demultiplexer](demultiplexer.md)** (demux): Does the opposite of multiplexer, i.e. has one *M* address inputs and 1 data input and *2^M* outputs. Depending on the given address, the input is redirected to *N*th output (while other outputs are 0).
|
||||
- **[RS](rs.md) flip-flop**: Possibly the simplest flip-flop (a sequential circuit) with two inputs, *R* (reset) and *S* (set), which can remember 1 bit of information (this bit can be set to 1 or 0 using the inputs). It can be implemented with two NOR gates.
|
||||
- **[decoder](decoder.md)**: Has *M* inputs and *2^M* outputs. It sets *N*th output to 1 (others are 0) where *N* is the binary number on the input. I.e. decoder converts a binary number into one specific signal. It can be implemented as a demultiplexer whose data input is always 1.
|
||||
- **[encoder](encoder.md)**: Does the opposite of encoder, i.e. has *2^M* inputs and *M* outputs, expects exactly one of the inputs to be 1 and the rest 0s, the output is a binary number representing the input that's 1.
|
||||
- **[ALU](alu.md)** (arithmetic logic unit): A more complex circuit capable of performing a number of logic and arithmetic operations. It is a part of a [CPU](cpu.md).
|
||||
- TODO: more
|
||||
- ...
|
||||
- TODO: flip-flops, more
|
||||
|
||||
## Minimization/Transformation Of Logic Circuits
|
||||
|
||||
Minimization (or optimization) is a crucial and **extremely important** part of designing logic circuits -- it means finding a logically equivalent circuit (i.e. one that behaves the same in regards to its [input/output](io.md), that is its truth table stays the same) that's smaller (composed of fewer gates); the motivation, of course, being saving resources (money, space, ...) and potentially even making the circuit faster. We may also potentially perform other transformations depending on what we need; for example we may wish to minimize the delay (longest path from input to output) or transform the circuit to only use [NAND](nand.md) gates (because some hardware manufacturing technologies greatly prefer NAND gates). All in all when designing a logic circuit, we basically always perform these two main steps:
|
||||
|
||||
1. Design the circuit to do what we want.
|
||||
2. Minimize (and/or otherwise transform) it so as to [optimize](optimization.md) it.
|
||||
|
||||
Some basic methods of minimization include:
|
||||
|
||||
- **algebraic methods**: We use known logic formulas to simplify the logic expression representing our circuit. This is basically the same as simplifying fractions and similar mathematical expressions. Some common formulas we use:
|
||||
- **De Morghan Laws**: TODO
|
||||
- TODO ...
|
||||
- **Karnaugh maps**: TODO
|
||||
- **Quine McCluskey**: TODO
|
||||
- ...
|
||||
|
||||
Example of minimization will follow in the example section.
|
||||
|
||||
## Example
|
||||
|
||||
TODO
|
||||
One of the simplest logic circuits is the two-bit half adder which takes two input bits, *x* and *y*, and outputs their sum *s* and [carry over](carry.md) *c* (which will become important when chaining together more such adders). Let us write a truth table of this circuit (note that adding in [binary](binary.md) behaves basically the same as how we add by individual digits in decimal):
|
||||
|
||||
| x | y | s | c |
|
||||
| --- | --- | --- | --- |
|
||||
| 0 | 0 | 0 | 0 |
|
||||
| 1 | 0 | 1 | 0 |
|
||||
| 0 | 1 | 1 | 0 |
|
||||
| 1 | 1 | 0 | 1 |
|
||||
|
||||
Notice that this circuit is combinational -- its output (*s* and *c*) only depends on the input values *x* and *y* and nothing else, which is why we can write such a nice table.
|
||||
|
||||
OK, so now we have the circuit behavior specified by a truth table, let's continue by designing the actual circuit that implements this behavior. Let us start by writing a logic expression for each output (& = AND, | = OR, ! = NOT, ^ = XOR):
|
||||
|
||||
*s = x ^ y*
|
||||
|
||||
*c = x & y*
|
||||
|
||||
We see the expressions are quite simple, let us now draw the actual circuit made of the basic logic gates:
|
||||
|
||||
```
|
||||
___
|
||||
x --.------|XOR|--- s
|
||||
\ .--|___|
|
||||
\/
|
||||
/\ ___
|
||||
/ '--|AND|--- c
|
||||
y --'------|___|
|
||||
|
||||
```
|
||||
|
||||
And that's it -- this circuit is so simple we can't simplify it further, so it's our actual result (as an exercise you may try to imagine we don't have a XOR gate available and try to replace it by AND, OR and NOT gates).
|
||||
|
||||
Next we can expand our half added to a full adder -- a full adder takes one more input *z*, which is a carry over from a previous adder and will be important when chaining adders together. Let's see the truth table of a full adder:
|
||||
|
||||
| x | y | z | s | c |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 0 | 0 | 0 | 0 | 0 |
|
||||
| 1 | 0 | 0 | 1 | 0 |
|
||||
| 0 | 1 | 0 | 1 | 0 |
|
||||
| 1 | 1 | 0 | 0 | 1 |
|
||||
| 0 | 0 | 1 | 1 | 0 |
|
||||
| 1 | 0 | 1 | 0 | 1 |
|
||||
| 0 | 1 | 1 | 0 | 1 |
|
||||
| 1 | 1 | 1 | 1 | 1 |
|
||||
|
||||
Let's try to make boolean expressions for both outputs now. We may notice *c* is 1 exactly when at least two of the inputs are 1, which we may write as
|
||||
|
||||
*c = (x & y) | (x & z) | (y & z)*
|
||||
|
||||
However, using the formula *(a & c) | (b & c) = (a ^ b) & c* , we can simplify (minimize) this to an expression that uses one fewer gate (notice there is one fewer operator)
|
||||
|
||||
*c = (x & y) | ((x ^ y) & z)*
|
||||
|
||||
The expression for *s* is not so clear though -- here we can use a method that always works: we simply look at all the lines in the truth table that result in *s = 1* and write them in "ORed" form as
|
||||
|
||||
*s = (x & !y & !z) | (!x & y & !z) | (!x & !y & z) | (x & y & z)*
|
||||
|
||||
Which we can also actually minimize (as an exercise try to figure out the formulas we used :p)
|
||||
|
||||
*s = ((x ^ y) & !z) | (!(x ^ y) & z)*
|
||||
|
||||
*s = (x ^ y) ^ z*
|
||||
|
||||
Now finally we can draw the full adder circuit
|
||||
|
||||
```
|
||||
___
|
||||
x ---.------|AND|--------------. ___
|
||||
\ .---|___| ___ '--|OR |--- c
|
||||
/ .----|AND|---|___|
|
||||
y --.-' \ / .---|___|
|
||||
\ \ ___ / /
|
||||
\ '--|XOR|-'----.
|
||||
'-----|___| / \ ___
|
||||
/ '-|XOR|---------- s
|
||||
z ----------------'---------|___|
|
||||
```
|
||||
|
||||
Now let us spectacularly combine one half adder (HA) and three full adders (FA) into one magnificent 4 bit adder. It will be adding two 4bit numbers, *a* (composed of bits *a0* to *a3*) and *b* (composed of bits *b0* to *b3*). Also notice how the carry bits of lower adders are connected to carry inputs of the higher full adders -- this is the same principle we use when adding numbers manually with pen and paper. The resulting sum *s* is composed of bits *s0* to *s3*. Also keep in mind the circuit is still combinational, i.e. it has no memory, no clock input and adds the numbers in a "single run".
|
||||
|
||||
```
|
||||
___
|
||||
a3 -----|FA |-- c3
|
||||
b3 -----| |------- s3
|
||||
.--|___|
|
||||
'--------.
|
||||
___ | c2
|
||||
a2 -----|FA |-'
|
||||
b2 -----| |------- s2
|
||||
.--|___|
|
||||
'--------.
|
||||
___ | c1
|
||||
a1 -----|FA |-'
|
||||
b1 -----| |------- s1
|
||||
.--|___|
|
||||
'--------.
|
||||
___ | c0
|
||||
a0 -----|HA |-'
|
||||
b0 -----|___|------- s0
|
||||
```
|
Loading…
Reference in New Issue