PMOD DTx2
Note
To install the Xyloni USB drivers and EFINIX IDE follow the guidelines under this GitHub repository
- For this project you also need the TANG DTx2 or a PMOD DTx2 with equivalent pinout

- Open EFINIX IDE.
Create a Project
- File-->Create Project...

- Set the project name, path and choose the model of your FPGA: Trion T8F81 C2

- Press Ok and finish.
Create the Top Level Module
- Create a new Verilog file
- File --> New File...

- I like to call the top level module "main.v"

- Go to Edit Project

- Select the Design tab and change the Top Module/Entity to "main"

-
Press the Ok button
-
Write the code below under the main.v to toggle the onboard LEDs
module main(
input clk,
input [1:0] BUTTON,
output [3:0] LEDY,
output [7:0] LEDx8
);
assign LEDY[0] = BUTTON[0];
wire [7:0] count;
// 8-bit hexadecimal counter
counterHex counter (
.clk (clk),
.reset (BUTTON[1]),
.value (count)
);
// Display 00 -> 01 -> ... -> 0F
PMOD_DTx2_Driver display (
.clk (clk),
.digit1 (count[7:4]),
.digit2 (count[3:0]),
.LEDx8 (LEDx8)
);
endmodule
- This project requires two more .v files to be written
- "PMOD_DTx2_Driver.v" to interface the PMOD
module PMOD_DTx2_Driver (
input wire clk,
input wire [3:0] digit1,
input wire [3:0] digit2,
output reg [7:0] LEDx8
);
// 33.33 MHz clock
// Multiplex every 1 ms
localparam integer COUNT_MAX = 33_329;
reg [15:0] counter;
reg active_digit;
reg A;
reg B;
reg C;
reg D;
reg E;
reg F;
reg G;
// =========================================================
// 7-segment decoder
//
// {A,B,C,D,E,F,G}
//
// Active LOW:
// 0 = segment ON
// 1 = segment OFF
//
// Supports hexadecimal 0-F
// =========================================================
function [6:0] seven_segment;
input [3:0] value;
begin
case (value)
// ABCDEFG
4'h0: seven_segment = 7'b0000001;
4'h1: seven_segment = 7'b1001111;
4'h2: seven_segment = 7'b0010010;
4'h3: seven_segment = 7'b0000110;
4'h4: seven_segment = 7'b1001100;
4'h5: seven_segment = 7'b0100100;
4'h6: seven_segment = 7'b0100000;
4'h7: seven_segment = 7'b0001111;
4'h8: seven_segment = 7'b0000000;
4'h9: seven_segment = 7'b0000100;
// Hexadecimal A-F
4'hA: seven_segment = 7'b0001000; // A
4'hB: seven_segment = 7'b1100000; // b
4'hC: seven_segment = 7'b0110001; // C
4'hD: seven_segment = 7'b1000010; // d
4'hE: seven_segment = 7'b0110000; // E
4'hF: seven_segment = 7'b0111000; // F
default: seven_segment = 7'b1111111;
endcase
end
endfunction
always @(posedge clk) begin
// =====================================================
// Multiplexing timer
// =====================================================
if (counter == COUNT_MAX) begin
counter <= 0;
active_digit <= ~active_digit;
end
else begin
counter <= counter + 1'b1;
end
// =====================================================
// Select which digit to display
// =====================================================
if (active_digit == 1'b0) begin
{A,B,C,D,E,F,G} = seven_segment(digit1);
// Digit 1 selected
LEDx8[0] <= 1'b0;
end
else begin
{A,B,C,D,E,F,G} = seven_segment(digit2);
// Digit 2 selected
LEDx8[0] <= 1'b1;
end
// =====================================================
// Physical PMOD mapping
// =====================================================
LEDx8[1] <= C;
LEDx8[2] <= A;
LEDx8[3] <= B;
LEDx8[4] <= D;
LEDx8[5] <= E;
LEDx8[6] <= G;
LEDx8[7] <= F;
end
endmodule
- And the "counterHEX.v"
module counterHex (
input wire clk,
input wire reset,
output reg [7:0] value
);
// 33.33 MHz clock
// 100 ms = 3,300,000 clock cycles
localparam integer COUNT_MAX = 3_300_000;
reg [23:0] counter;
initial begin
counter = 0;
value = 0;
end
always @(posedge clk) begin
// Reset counter when button is pressed
if (reset == 1'b0) begin
counter <= 0;
value <= 0;
end
// Otherwise count every 100 ms
else if (counter == COUNT_MAX) begin
counter <= 0;
value <= value + 1'b1;
end
else begin
counter <= counter + 1'b1;
end
end
endmodule
Floor Planner
- In order for FPGA to realize the functions of the code, the ports involved in the code must be bound to the actual pins of FPGA.
- Open the Interface Designer

- This time, instead of assigning the pins one by one, we are going to import a csv file with the pins already assigned.
- Press the "Import Design" button

- Select "Comma Separated File (.csv)"

- Point to the "Xyloni_Pinout.csv" file

-
Press "Next" and "Finish"
-
All pins for this project should be imported accordingly with the correct names that match the main module header.

Synthesis
- On the dashboard press the button "Synthesize"

- If the button "Toggle Automated Flow" is enable, the rest of the sequence (Place --> Route --> Generate Bitstream) will happen automatically.

Download to Device
- Make sure Xyloni is connected to your computer and press the "Open Programmer" button

-
The programmer will detect your board automatically and it will select the .hex file to be sent to the board
-
Press "Start Program"

- Wait until programming operation is completed

- Press the button to toggle the LED