Connection of peripheral modules to MIPSfpga, using the example of the Pmod KYPD keyboard
Hello! We are one of the winners of the MIPfpga hackathon , in this article we will explain how to connect modules to the system on a chip based on the MIPSfpga using the example of the Pmod KYPD keyboard. Also we will familiarize with writing of the program for management of the connected modules
Pmod KYPD is a 16-button keypad with numbers in hexadecimal format (0-F). The polling is done by alternately feeding logical 0 on each column and reading the status of the rows. If at the time of polling a column one of the buttons in it is pressed, the corresponding line will produce a logical 1. First you need the MIPSfpga sources.
Description and installation instructions are present, in short, in order to be able to just run the script and the project is assembled, you need:
- put the MIPSfpga source in a folder
C: \ MIPSfpga;
and MIPSfpga-plus directory:
C: \ github \ mipsfpga-plus;
Next, in the folder C: \ github \ mipsfpga-plus \ boards, select your board, for me it is de0_cv, and execute the make_project script. The project that you want to run will be in C: \ github \ mipsfpga-plus \ boards \ de0_cv \ project.
If there is no project for your board, then you can select the most suitable by the number of logical cells and change the destination;
“You will also need a compiler, a Codescape linker, and a USB-UART converter, for example, pl2303hx or ch340.
Connecting the keyboard and USB-UART converter to the board
The keyboard will be directly connected to the AHB-Lite bus. To integrate the keyboard into the system, we created the decoder.v module. This module works as follows: every millisecond one of the columns and is polled. if at that moment the button in this column was pressed. then the corresponding line will produce a logical one. Each combination row + column corresponds to a digit from 0 to F. This digit is written to the register and transferred to the processor memory via the bus. With the help of software data from the memory are displayed on the indicator.
parameter ZERO = 8'b11100111; // row, col parameter ONE = 8'b01110111; Parameter TWO = 8'b01111011; parameter THREE = 8'b01111101; parameter FOUR = 8'b10110111; Parameter FIVE = 8'b10111011; Parameter SIX = 8'b10111101; parameter SEVEN = 8'b11010111; Parameter EIGHT = 8'b11011011; Parameter NINE = 8'b11011101; Parameter TEN = 8'b01111110; Parameter ELEVEN = 8'b10111110; Parameter TWELVE = 8'b11011110; parameter THIRTEEN = 8'b11101110; parameter FOURTEEN = 8'b11101101; Parameter FIFTEEN = 8'b11101011;
always @ (posedge i_clk or negedge i_rst_n) begin if (i_rst_n == 1'b0) begin col <= 4'b1110; end else begin if (counter == 31'b111001001110000111000000) begin col <= {col [0], col [3: 1]}; end end end
always @ * begin if (i_rst_n == 0) begin number <= 4'b0; end else begin case ({i_row1, i_row2, i_row3, i_row4, col [0], col [1], col [2], col [3]}) ZERO: begin number <= 4'b0000; end ONE: begin number <= 4'b0001; end TWO: begin number <= 4'b0010; end THREE: begin number <= 4'b0011; end FOUR: begin number <= 4'b0100; end FIVE: begin number <= 4'b0101; end SIX: begin number <= 4'b0110; end SEVEN: begin number <= 4'b0111; end EIGHT: begin number <= 4'b1000; end NINE: begin number <= 4'b1001; end TEN: begin number <= 4'b1010; end ELEVEN: begin number <= 4'b1011; end TWELVE: begin number <= 4'b1100; end THIRTEEN: begin number <= 4'b1101; end FOURTEEN: begin number <= 4'b1110; end FIFTEEN: begin number <= 4'b1111; end default: begin number <= number; end endcase end end
always @ (posedge i_clk or negedge i_rst_n) begin if (i_rst_n == 0) begin counter = 31'b0; end else begin if (counter == 31'b111001001110000111000011) begin counter = 31'b0; end else begin counter = counter + 1'b1; end end end
assign o_number = number; assign o_col = col;
endmodule
We connect to the project a file with the module described above. In the top-level file, we have this de0_cv.v, we add the following lines:
Actually, this is the address at which registers will be available. The final touch will be writing a program that displays the numbers on a seven-segment display.
Program code
#include "mfp_memory_mapped_registers.h"
int main () { int n = 0;
for (;;) {
MFP_7_SEGMENT_HEX = MFP_PMOD_KYPD; MFP_GREEN_LEDS = n ++;
}
return 0; }
Generate the motorola_s_record file:
08_generate_motorola_s_record_file
Check to which COM port the USB UART converter is connected:
11_check_which_com_port_is_used
Modify the 12_upload_to_the_board_using_uart file: