From 991d883dfa7f45e1802ab581bd80d91cca9b35c9 Mon Sep 17 00:00:00 2001 From: lshprung Date: Wed, 28 Oct 2020 11:33:16 -0700 Subject: Post-class 10/28 --- 14.md | 4 + 15.1.png | Bin 0 -> 621 bytes 15.10.png | Bin 0 -> 25464 bytes 15.11.png | Bin 0 -> 7024 bytes 15.2.png | Bin 0 -> 2255 bytes 15.3.png | Bin 0 -> 10483 bytes 15.4.png | Bin 0 -> 9164 bytes 15.5.png | Bin 0 -> 3185 bytes 15.6.png | Bin 0 -> 12437 bytes 15.7.png | Bin 0 -> 15649 bytes 15.8.png | Bin 0 -> 8519 bytes 15.9.png | Bin 0 -> 8471 bytes 15.md | 140 +++++++++++++++++++++++++ 16.1.png | Bin 0 -> 6582 bytes 16.2.png | Bin 0 -> 6354 bytes 16.3.png | Bin 0 -> 23343 bytes 16.md | 343 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 17 files changed, 487 insertions(+) create mode 100644 15.1.png create mode 100644 15.10.png create mode 100644 15.11.png create mode 100644 15.2.png create mode 100644 15.3.png create mode 100644 15.4.png create mode 100644 15.5.png create mode 100644 15.6.png create mode 100644 15.7.png create mode 100644 15.8.png create mode 100644 15.9.png create mode 100644 15.md create mode 100644 16.1.png create mode 100644 16.2.png create mode 100644 16.3.png create mode 100644 16.md diff --git a/14.md b/14.md index 04916f8..2242cbb 100644 --- a/14.md +++ b/14.md @@ -84,3 +84,7 @@ ![circuit](14.9.png) ![truth table](14.10.png) ![graphical symbol](14.11.png) + +--- + +[Datapath concepts: buses, registers, multi-bit muxes, shift registers ->](15.md) diff --git a/15.1.png b/15.1.png new file mode 100644 index 0000000..a54f9e3 Binary files /dev/null and b/15.1.png differ diff --git a/15.10.png b/15.10.png new file mode 100644 index 0000000..4b28353 Binary files /dev/null and b/15.10.png differ diff --git a/15.11.png b/15.11.png new file mode 100644 index 0000000..e0d1b5d Binary files /dev/null and b/15.11.png differ diff --git a/15.2.png b/15.2.png new file mode 100644 index 0000000..e1a05b8 Binary files /dev/null and b/15.2.png differ diff --git a/15.3.png b/15.3.png new file mode 100644 index 0000000..3760c1d Binary files /dev/null and b/15.3.png differ diff --git a/15.4.png b/15.4.png new file mode 100644 index 0000000..63a3e7d Binary files /dev/null and b/15.4.png differ diff --git a/15.5.png b/15.5.png new file mode 100644 index 0000000..5684282 Binary files /dev/null and b/15.5.png differ diff --git a/15.6.png b/15.6.png new file mode 100644 index 0000000..c43bdcc Binary files /dev/null and b/15.6.png differ diff --git a/15.7.png b/15.7.png new file mode 100644 index 0000000..5686552 Binary files /dev/null and b/15.7.png differ diff --git a/15.8.png b/15.8.png new file mode 100644 index 0000000..ae5c861 Binary files /dev/null and b/15.8.png differ diff --git a/15.9.png b/15.9.png new file mode 100644 index 0000000..3994167 Binary files /dev/null and b/15.9.png differ diff --git a/15.md b/15.md new file mode 100644 index 0000000..4d56061 --- /dev/null +++ b/15.md @@ -0,0 +1,140 @@ +[\<- Sequential design basics](14.md) + +--- + +# Datapath concepts: buses, registers, multi-bit muxes, shift registers + +## Buses and registers + +### Datapath elements + +- Before we get into more sequential design, taking a detour to learn some concepts/abstractions/terminology associated with multi-bit values + - Buses + - Registers + - Multi-bit muxes +- Also a good time to learn some more Verilog before returning to sequential design + +### What is a bus? + +- A set of wires generally treated as a single entity +- Often expressed/labeled like an array of wires + - E.g., data[31:0] + - Range from 31 to 0 (encompasses 32 values) + - Represents a bus called data that has 32 individual bits/values (32 bit bus) + - Each index denotes a different wire +- Schematic notation uses a slash and a number to indicate bus "width" + - The below diagram represents a 4 bit bus + +![diagram](15.1.png) + +### Registers + +- A group of flip-flops used to store the individual bits of some multi-bit value + - E.g., a 32-bit register is a group of 32 flip-flops, with each flop holding one of the 32 bits +- Schematic representation is a flip-flop with buses connected to the input and output + - Bus width implies the number of flip-flops + +![diagram](15.2.png) + +--- + +## Load enables + +- There is \*always\* a value on the D input of a register; wires always have a value + - There may be times when it is undesirable for that value to be captured in the register +- If a bus connects to a number of registers, you want to control which one loads data + - `E` is the load enable input in the diagram below + +![using a multiplexer](15.3.png) +![clock gating](15.4.png) + +### Register w/load enable + +- Previous pictures intended to show concept in detail, i.e., how it works +- Abstraction just uses E to represent load enable capability + - The muxing or clock gating is implied +- This 8-bit register just needs to show one enable (E) + +![diagram](15.5.png) + +### Load enable usage example + +- ALU takes two input operands to generate a result +- What if we just had one bus to get the operands to the ALU? + - Use registers to hold the operands + - Use load enables to control when the value on the bus is loaded into which register +- Maybe the result gets captured in a register, but only if the answer is correct + - Another use of the load enable concept + +### Block diagram w/load enables + +- Datapath with controls + +![diagram](15.6.png) + +--- + +## Multi-bit muxes + +- We've seen buses, which are actually multiple wires +- We've seen registers, which are multiple flip-flops +- Multiplexers are also often multi-bit + - Drawn as a single instance in a schematic + - Bused data inputs and outputs imply multiple instances + - Select signals still a function of the number of choices, \*not\* the width of the data buses + +### 8-bit wide 4:1 mux + +![diagram](15.7.png) + +--- + +## Shift register concept + +- A special type of register that chains the flip-flops together so that bits can move position +- Uses: + - multiplying/dividing by 2 + - a type of counter + - tracking the position of an object + - serial \<-> parallel conversion + +### Basic Shift Register + +![circuit](15.8.png) +![a sample sequence](15.9.png) + +### Loadable shift register + +- Can either shift right, or load a set of 4 bits at one time + - Parallel inputs: D3, D2, D1, D0 + +![diagram](15.10.png) + +--- + +## Universal shift register + +### Other shift register functions + +- Previous example had "shift right" and "load" functions +- Other functions could be "shift left" and "hold" + - hold = don't change anything +- A universal shift register (USR) provides all four functions + - What would this look like? + +### One bit of the USR + +- Assuming 2-bit encodings in the table + +|S1S0|function | +|----|-------- | +|00 |Shift left | +|01 |Shift right| +|10 |load | +|11 |hold | + +![diagram](15.11.png) + +--- + +[Procedural Verilog and specifying sequential circuits in Verilog ->](16.md) diff --git a/16.1.png b/16.1.png new file mode 100644 index 0000000..0d74b6c Binary files /dev/null and b/16.1.png differ diff --git a/16.2.png b/16.2.png new file mode 100644 index 0000000..66cc250 Binary files /dev/null and b/16.2.png differ diff --git a/16.3.png b/16.3.png new file mode 100644 index 0000000..b71e0f2 Binary files /dev/null and b/16.3.png differ diff --git a/16.md b/16.md new file mode 100644 index 0000000..bf4b602 --- /dev/null +++ b/16.md @@ -0,0 +1,343 @@ +[\<- Datapath concepts : buses, registers, multi-bit muxes, shift registers](15.md) + +--- + +# Procedural Verilog and specifying sequential circuits in Verilog + +## Conditional assignment + +- Mux can be modeled as a conditional assign statement + - Mux select is condition + - "Port1" listed first + +``` +module mux2to1(20, 21, s, f); + input w0, w1, s; + output f; + + assign f = s ? w1 : w0; + +endmodule +``` + +--- + +## "Always" block concepts + +### Strange concepts ahead + +- The next topic we will be looking at is the concept of procedural statements + - Often referred to as an "always" block because it starts with the keyword "always" +- Can be a difficult concept to wrap your head around + - Prime example of the idiosyncrasies of how Verilog was developed +- Once you get the hang of it, makes Verilog so much easier to specify complex circuits +- Always keep in mind that we are **describing hardware**, not writing software code + +### The always block + +- Assign statements are a relatively direct modeling of hardware concepts +- Always block allows for specifying functionality in a high-level fashion + - Simulation tools interpret the behavior + - Synthesis tools translate into an implementation structure + - Quartus doesn't implement structure you specify +- Code inside block evaluated sequentially +- Use of begin/end for multiple statements + +### Sensitivity list + +- Most uses of always block use an `@` construct to indicate when block should be evaluated + - Called the sensitivity list +- Might be easier to think of "always" as "whenever" +- For combinational logic, needs to list all inputs to the logic + - Originally required complete listing + - At some point, `*` (wildcard) was added as a convenience + +### The "reg" variable type + +- As with other languages, variables are set to values when on left of equal sign + - `A = B & C` +- Sometimes an always block doesn't execute + - Conditions in sensitivity list not met +- Simulator needs to maintain variable settings from the last time the always block \*did\* execute + - Led to requiring variables to be of type "reg" + +--- + +### If-statement examples + +### Mux with if-else statement + +- If-else construct doesn't as obviously match a hardware structure, but is useful for specifying behavior +- `f` is defined as reg, as well as output + - It needs to be declared as reg because it is being used in the always block + +``` +module mux2to1(w0, w1, s, f); + input w0, w1, s; + output reg f; + + always @(w0, w1, s) + if (s==0) + f = w0; + else + f = w1; + +endmodule +``` + +### A few other constructs + +- Buses are like arrays + - wire [1:0] S; (or [0:1] S) + - Individual bits/wires can be identified: S[1] +- Buses can be "created" by concatenation + - S[1:0] = {S1, S0} +- Specifying constants: \'b\ + - 2'b11 + - Can also do 4'hF (== 4'b1111) + - n is the number of bits, not the # of digits + - b vs h indicates format of constant (binary vs hex) + +### 4:1 mux using always @(\*) + +- The wildcard is used in place of listing out all our inputs + +``` +module mux4to1(w0, w1, w2, w3, S, f); + input w0, w1, w2, w3; + input [1:0] S; + output reg f; + + always @(*) + if(S == 2'b00) + f = w0; + else if(S == 2'b01) + f = w1; + else if (S == 2'b10) + f = w2; + else if (S == 2'b11) + f = w3; + +endmodule +``` + +### Bus enumeration + +- Example of both styles: 0:3 and 1:0 + +``` +module mux4to1(W, S, f); + input [0:3] W; + input [1:0] S; + output reg f; + + always @(W, S) + if(S == 0) + f = W[0]; + else if(S == 1) + f = W[1]; + else if (S == 2) + f = W[2]; + else if (S == 3) + f = W[3]; + +endmodule +``` + +--- + +## Case-statement examples + +### The case statement + +- Each 'if' clause is checking for a different value of S +- Case statement allows for a more efficient way to specify: + +``` +always @(*) + case (S) + 0: f=W[0]; + 1: f=W[1]; + 2: f=W[2]; + 3: f=W[3]; + endcase +``` + +### Another case example + +- Concatenation operator dynamically creates a 3-bit variable +- Default case can be used to catch all other cases + +``` +module dec2to4(W, En, Y); + input [1:0] W; + input En; + output reg [0:3] Y; + + always @(W, En) + case({En, W}) + 3'b100: Y = 4'b1000; + 3'b101: Y = 4'b0100; + 3'b110: Y = 4'b0010; + 3'b111: Y = 4'b0001; + default: Y = 4'b0000; + endcase; + +endmodule +``` + +- Remember: the curly braces represent concatenation (which means that the case argument is actually a 3-bit number) + +### More on case statements + +- Previous case statement could have been written + +``` +if(En==1 & W==2'b00) Y = 4'b1000; +else if(En==1 & W==2'b01) Y = 4'b0100; +else if(En==1 & W==2'b10) Y = 4'b0010; +else if(En==1 & W==2;b11) Y = 4'b0001; +else Y = 4'b0000; +``` + +- If all possible cases not listed, need default + +### One more example + +- The ALU we looked at had two mux'ing circuits: + - selective inversion for operand B + - selection for the final result to be either the output of the adder or a true/false indication +- How to implement these as case statements, using the 2-bit command as the selection quantity? + - In place of F1,F0, let's use Command[1:0] + +### Example usage of case + +- If specifying ALU in Verilog, Result could be set in a case statement + +``` +Always @(*) + case(Command) + 2'b00: Result = Sum; + 2'b01: Result = Sum; + 2'b11: Result = {0,0,0,LT}; + default: Result = Sum; + endcase +``` + +--- + +## Modeling a flip-flop + +- Use edge of clock in sensitivity list + - Models the snapshot behavior of a flop + - No reason to execute the code except for when there's a rising edge + +``` +module flipflop(D, Clock, Q); + input D, Clock; + output reg Q; + + always @(posedge Clock) + Q = D; + +endmodule +``` + +- `posedge` is a keyword in Verilog + - We use it in the above example to say that our flip-flop is a positive edge trigger + +--- + +## The subtlety of non-blocking assignments + +### Multiple flops in the same block + +- Because always block is evaluated sequentially, need to make sure behavior is as intended + - Both Q1 and Q2 would get D in this example + +``` +module example5_3(D, Clock, Q1, Q2); + input D, Clock; + output reg Q1, Q2; + + always @(posedge Clock) + begin + Q1 = D; + Q2 = Q1; + end + +endmodule +``` + +![diagram](16.1.png) + +### Non-blocking statements + +- Forces simulator to update in parallel +- Generally used when modeling flops + - Doesn't make a difference in simple designs + - Multiple interacting synchronous modules + +``` +module example5_4(D, Clock, Q1, Q2); + input D, Clock; + output reg Q1, Q2; + + always @(posedge Clock) + begin + Q1 <= D; + Q2 <= Q1; + end + +endmodule +``` + +![diagram](16.2.png) + +- `<=` is the non-blocking statement + - It looks like at less than or equal to sign, but it is supposed to represent more of an arrow to the left + - Purpose is to use over `=` in the above example because it assigns to `Q2` the value of `Q1` before it was set to the value of `D` (non-sequential) (as opposed to setting `Q2` to the value of `Q1` after it was set to the value of `D`) + - Good practice to use + +--- + +## Modeling a register, with load enable + +### Modeling registers + +- Registers are just multi-bit flip-flops + - Buses for inputs and outputs +- Load enables control updates + - But not in sensitivity list, just posedge clock + +``` +Module fourBitReg(D, clock, En, Q); + input [3:0] D; + input En, clock; + Output reg [3:0] Q; + + Always @(posedge clock) + if(En) Q = D; + +Endmodule +``` + +--- + +## Separating combinational logic from state updates + +### A note about usage of always + +- There are multiple ways to specify sequential circuits in Verilog +- For our sanity, we will use two always blocks to avoid confusion + - One for combinational logic (`always @(*)`) + - Causes simulator to evaluate whenever an input changes + - One for flip-flops (`always @(posedge clk)`) + - Causes simulator to only evaluate at the clock edge, since that's the only time the output can change + +### Verilog for sequential circuits + +- Combinational logic generates "next" value as a function of "current" value +- Flip-flops update "current" value with "next" + +![diagram](16.3.png) -- cgit