Commit fb5df750 by Alan Wood

### Merge branch 'andrew-tutorial-tweaks' into 'tutorial'

```Andrew tutorial tweaks

This is the first time I've tried GitLab so I don't know if I've got the process right...

See merge request !6```
parents 934a2c60 65dd3e62
 ... ... @@ -52,14 +52,14 @@ assign y = a2[1] | a2[0]; ## Concatenation and Replication ```verilog assign y2 = {a,b}; assign y2 = {a,1'b0}; assign y3 = {a,b,1'b1}; assign y3 = {a,2'b10}; assign y3 = {a,a2}; assign y3 = {a,a2[0],1'b1}; assign {y2,y} = {y3[1:0],a}; assign y3 = {a,2{1'b1}}; assign y2 = {a,b}; // creates a 2-bit signal of a with b assign y2 = {a,1'b0}; // a with 1 bit binary 0 (constant) assign y3 = {a,b,1'b1}; // a with b with binary 1 (constant) assign y3 = {a,2'b10}; // a with 2 binary bits 1, 0 assign y3 = {a,a2}; // a with a2 (a2 is 2 bits) assign y3 = {a,a2[0],1'b1}; // a with single bit from a2 with 1 assign {y2,y} = {y3[1:0],a}; // multiple assignment: creates y2 as 2 bits from y3 and y as a assign y3 = {a,2{1'b1}}; // a with 2 lots of binary 1 ``` ## Shifting ... ... @@ -83,6 +83,7 @@ assign y3 = {y3[0],y3[2:1]}; ``` ### Rotate right 2 bit ```verilog assign y3 = {y3[1:0],y3[2]}; ``` ... ... @@ -103,6 +104,8 @@ assign max = (a > b) ? a : b; ## If/Else (NB not sequential, actually 'network routings') ```verilog if(a < b) assign min = a; ... ... @@ -121,7 +124,7 @@ else ```verilog if(boolean) begin begin // need begin...end if >1 line of code within condition // begin code end else ... ... @@ -132,7 +135,7 @@ else ## Synthesis of Z and X Values Z values can only be synthesised by tristate bufferes and thus infer them Z values can only be synthesized by tristate buffers and thus infer them these have output enable inputs to control their output state for example here is a single bit tristate buffer with an output enable ... ... @@ -167,14 +170,13 @@ always @(sensitivity list) end [optional label] ``` ### Procedual Assignment ### Procedural Assignment ```verilog [variable] = [expression]; // blocking, assigned before next statement // like normal C [variable] <= [expression]; // non blocking, assigned at end of always // block [variable] <= [expression]; // non blocking, assigned at end of always block ``` Blocking tends to be used for combinational circuits, non-blocking for ... ... @@ -185,7 +187,7 @@ with one of the variable data types, which are reg, integer, real, time, and realtime. The reg data type is like the wire data type but used with a procedural output. The integer data type represents a fixed-size (usually 32 bits) signed number in 2's-complement format. Since its size is fixed, we usually don't use it in synthesis. The other data types are for modeling and usually don't use it in synthesis. The other data types are for modelling and simulation and cannot be synthesized. ## Registers ... ... @@ -194,7 +196,7 @@ A register is simple memory wire to hold state, normally implemented as D-Types ```verilog output reg output reg // single-bit, use [] syntax above for >1 bit registers ``` ## Conditional Examples ... ... @@ -212,7 +214,7 @@ en a1 a2 y ```verilog module pri_encoder ( ( // 4 bit input, 3 bit output input wire [4:1] r, output wire [2:0] y ) ... ... @@ -239,9 +241,9 @@ module decoder_1 input wire en, output reg [3:0] y ) always @* always @* // @* means 'Anything needed'; clearer to list required resources but danger of missing items if(~en) y = 4'b0000; y = 4'b0000; // 4-bit wide, binary representation: 0000 else if(a == 2'b00) y = 4'b0001; else if(a == 2'b01) ... ... @@ -324,7 +326,7 @@ case statement. When synthesized, a parallel case statement usually infers a multiplexing routing network and a non-parallel case statement usually infers a priority routing network. Unlike C where conditional constructs are executed serially using branches and jumps, with HDL these are realised by routing netowrks. networks. ### Casez ... ... @@ -338,7 +340,7 @@ module decoder_4 always @* casez ({en,a}) 3'b0??: y = 4'b0000; 3'b0??: y = 4'b0000; // casez also offers '?' 3'b100: y = 4'b0001; 3'b101: y = 4'b0010; 3'b110: y = 4'b0100; ... ... @@ -366,8 +368,8 @@ always @* y = a & b; ``` `y` is the output of two circuits which could be contridictary, this is not synthesiseable. Below is how this should have been writtten: `y` is the output of two circuits which could be contradictary, this is not synthesizable. Below is how this should have been written: ```verilog always @* ... ... @@ -380,7 +382,7 @@ always @* ### Incomplete sensitivity list Incomplete sensitivity list (missing `b`). `b` could change but the y output would not, causing unexpected behavior againg this is not synthesiseable. would not, causing unexpected behaviour again this is not synthesizable. ```verilog always @(a) ... ... @@ -404,10 +406,10 @@ always @* gt = 1'b1; // no eq assignment in branch else if(a == b) eq = 1'b1; // no gt assignment in branch // final else branch omiitted // final else branch omitted ``` Here we break both incomplete output assinment rules and branch According to Here we break both incomplete output assignment rules and branch. According to Verilog definition `gt` and `eq` keep their previous values when not assigned which implies internal state, unintended latches are inferred, these sort of issues cause endless hair pulling avoid such things. Here is how we could ... ... @@ -451,9 +453,9 @@ Similar errors can creep into case statements ```verilog case(a) 2'b00: y =1'b1; 2'b10: y =1'b0; 2'b11: y =1'b1; 2'b00: y = 1'b1; 2'b10: y = 1'b0; 2'b11: y = 1'b1; endcase ``` ... ... @@ -473,21 +475,21 @@ endcase ## Adder with carry ```verilog module adder #(parameter N=4) module adder #(parameter N=4) // input parameter N, default value of 4 if not specified. N will be the adder width here ( input wire [N-1:0] a,b, output wire [N-1:0] sum, output wire cout output wire cout // carry bit ); /* Constant Declaration */ localparam N1 = N-1; localparam N1 = N-1; // localparam: only visible within module /* Signal Declaration */ wire [N:0] sum_ext; wire [N:0] sum_ext; // NB not N-1 /* module body */ assign sum_ext = {1'b0, a} + {1'b0, b}; assign sum_ext = {1'b0, a} + {1'b0, b}; // excludes Nth bit assign sum = sum_ext[N1:0]; assign cout = sum_ext[N]; ... ... @@ -499,7 +501,7 @@ module adder_example output wire [3:0] sum4, output wire c4 ) // Instantiate a 4 bit adder // Instantiate a 4 bit adder - .N specifies parameter name N; connect a to a4, b to b4, sum to sum4, cout to c4 adder #(.N(4)) four_bit_adder (.a(a4), .b(b4), .sum(sum4), .cout(c4)); endmodule ... ...
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!