# Hardware Design with FPGA's

We are sorry but this course will not be running this term |

You can download the following sample projects:

- Schematic capture sample project: File:NOTgate.zip
- Verilog sample project: File:Verilogintro.zip
- A complete pin-mapping file
- NOTE! This mapping file has different names for the pins (such as SW instead of switches, and LEDG instead of LEDs)

- The following code will map a hexadecimal number to a 7-segment display. Note that you need the above pin mappings for it to work.

7segment |
---|

module hex2sevenseg(output wire [6:0] Segments, input wire [3:0] Hex); assign Segments[0] = !((Hex[1] & !Hex[0]) | (!Hex[3] & Hex[1]) | (Hex[2] & Hex[1]) | (!Hex[3] & Hex[2] & Hex[0]) |(Hex[3] & !Hex[2] & !Hex[1]) | (!Hex[3] & !Hex[2] & !Hex[0]) | (Hex[3] & Hex[2] & !Hex[0])); assign Segments[1] = !((!Hex[3] & !Hex[2]) | (!Hex[3] & !Hex[1] & !Hex[0]) | (!Hex[3] & Hex[1] & Hex[0]) | (Hex[3] & !Hex[1] & Hex[0]) | (!Hex[2] & !Hex[0])); assign Segments[2] = !((!Hex[3] & !Hex[1]) | (!Hex[3] & Hex[0]) | (!Hex[3] & Hex[2]) | (!Hex[1] & Hex[0]) |(Hex[3] & !Hex[2])); assign Segments[3] = !((Hex[3] & !Hex[1]) | (Hex[2] & Hex[1] & !Hex[0]) | (!Hex[3] & !Hex[2] & Hex[1]) | (!Hex[2] & !Hex[1] & !Hex[0]) | (!Hex[2] & Hex[1] & Hex[0]) | (Hex[2] & !Hex[1] & Hex[0])); assign Segments[4] = !((Hex[1] & !Hex[0]) | (Hex[3] & Hex[1]) | (Hex[3] & !Hex[0]) | (Hex[3] & Hex[2]) | (!Hex[2] & !Hex[0])); assign Segments[5] = !((!Hex[1] & !Hex[0]) | (Hex[3] & Hex[1]) | (Hex[3] & !Hex[2]) | (Hex[2] & !Hex[0]) | (!Hex[3] & Hex[2] & !Hex[1])); assign Segments[6] = !((Hex[1] & !Hex[0]) | (!Hex[2] & Hex[1]) | (Hex[3] & !Hex[2]) | (Hex[3] & Hex[0]) | (!Hex[3] & Hex[2] & !Hex[1])); endmodule //and you instansiate it like this hex2sevenseg(HEX0[6:0], rnd[3:0]); hex2sevenseg(HEX1[6:0], rnd[7:4]); hex2sevenseg(HEX2[6:0], rnd[11:8]); hex2sevenseg(HEX3[6:0], rnd[15:12]); |

## Contents

## ISA for the custom processor

http://www.doc.ic.ac.uk/~rs5010/isa_v02.txt

## Exercises session 3

Note that for all these exercises you can drive your module's clock signal using the clock generated by freqdiv, to make everything run at a more human interactive pace.

freqdiv |
---|

// A frequency divider module freqdiv(input clk, output reg divclk); reg [31:0]counterstate = 0; parameter [31:0] divammount = 10000000; always @ (posedge clk) begin counterstate = counterstate + 1; if (counterstate == divammount) begin divclk = ~divclk; counterstate = 0; end end endmodule |

- Make a counter that counts to a fixed value, then overflows to 0 and keeps going
- Make a random number generator using a counter with an enable signal.
- Make a variable frequency counter, that is, make it overflow to 0 when it has got to a certain value, instead of a fixed value. Make it increment an output register on every overflow. This should make a variable frequency counter.
- Using (one instance of) the following ALU block, compute A + B - C - D where A,B,C,D are some arbitrary 32 bit numbers.

ALU |
---|

// a very simple ALU module ALU(input [1:0] fselect, input [31:0] A, input [31:0] B, output reg [31:0] Result); always @ (*) begin //Multiplexer with fselect as selection //Note that N'bxx means a N bit literal with binary value xx case (fselect) 2'b00: Result = A + B; //do nothing 2'b01: Result = A - B; 2'b10: Result = A; 2'b11: Result = 0; endcase end endmodule |

- Make a counter that uses a switch as the clock input
- You might notice that when you flick the switch you actually generate more than one clock edge. This is called contact bounce. To avoid this you have to make a debounce circuit. Make sure you know what is going on in this code.
- Let a switch be a manual clock signal, i.e.
`always (@posedge SW[9]) begin`

. On the first flick of the clock switch, the value of the rest of the switches should be loaded into operand A. At the next flick, they should be loaded into operand B. The next flick should load the logic operation to be performed (i.e. load fselect), and display the result on the 7-segments or the LED's. - The following syntax for defining an array of words
`reg [31:0] memory_array [7:0]`

, which makes an array of 8 32 bit words, accessed as entire words using`memory_array[index]`

. Add one last cycle after fselect where you select a memory location to store the result on the next flick. Check that it did indeed store the result using the signal tap analyzer. - Make it so that you use a reserved switch to select if on every flick you do: either the value gets loaded (as per last time), or memory_array[value] gets loaded. Compute A + B - C - D using this method of storing intermediate results.
- Have a look at Linear Feedback Shift Registers. Make an enhanced random number generator using a 32 bit LFSR.

## Exercises session 2

1. Implement a 2to1 multiplexer (as a module) with the following specifications:

input A, 3 bits wide (tip: use the array notation) input B, 3 bits wide input select, 1 bit wide (tip: simply a wire) output Y, 3 bits wide

Elaboration: if select signal is zero (0), make Y output the A's value. if select signal is one (1),

make Y output the B's value.

(!) Note: example of a binary constant of width one with value zero: 1'b0. First value is the length

of the literal, b means that it is a binary literal and 0 is the value.

To test, either test the module directly in the simulator or (if doing it in hardware) use the

switches and LEDs.

2. Make a adder/subtractor/leftshift by one/right shift by one block that uses a 2 bit input to

select the operation. i.e. if select is : 00 then: result = A + B 01 then: result = A - B 10 then: result = A << 1 11 then: result = A >> 1

3. Make a 3-to-8 one-hot decoder (google what one-hot encoding is) hint: use a variable ammount of left shift, OR: note that the following syntax is valid

result[select] = 1; 4. Make a 8-to-3 priority encoder (google what priority-encoder is) hint: use nested if, else if, else if, .... else statement extra: try doing this with a for loop. Check the syntax on google 5. Make a module that can rotate an input to the left by 1 bit. hint: use a shift and the concatination operator to bring the last bit around 6. Make a module that takes a 3 bit control input that represents a number from 0 to 7, and uses

this to rotate to the left an input value by the specified number of bits. hint: use sucessive if statements to sequentially selectively rotate a temporary variable by

the corresponding power of 2.

## Creating a new project

- Put in some Verilog of your choice, such as:

`// Top level module: needs to have the same name as the project`

`// The inputs and outputs need to be things defined in the pin-planner in order to map to the real world`

module emptyproject( input [7:0] switches, output [7:0] LEDs, input CLOCK_50);

`// Instantiation of the "my_logic" module, called inst1`

`// The inputs and outputs are mapped to the actual pins here`

my_logic inst1(switches[0], switches[1], LEDs[0]);

`endmodule`

`// make any logic you want`

module my_logic(input in1, input in2, output out);

assign out = ~in1 & in2;

`endmodule`

## Simulating

To run the simulator run the following (or equivalent): C:\altera\12.0sp2\quartus\bin\quartus_sh --qsim

- 20.PNG