`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: Raptor Engineering // Engineer: Timothy Pearson // // Design Name: Remote Access Sample Design // Module Name: sample_demo // Project Name: Remote Access Sample Design // Target Devices: Any // Description: Remote Access Sample Design // // Dependencies: // // (c) 2007-2013 Timothy Pearson, Raptor Engineering // Released into the Public Domain // ////////////////////////////////////////////////////////////////////////////////// module main( input clk, // 100MHz clock // Serial port input serial_input, output serial_output); parameter RAM_ADDR_BITS = 14; wire [7:0] four_bit_output; // Output from the user program to the remote access module wire [7:0] four_bit_input; // Input to the user program from the remote access module wire [7:0] eight_bit_output; // Output from the user program to the remote access module wire [7:0] eight_bit_input; // Input to the user program from the remote access module wire [15:0] sixteen_bit_output; // Output from the user program to the remote access module wire [15:0] sixteen_bit_input; // Input to the user program from the remote access module wire [7:0] remote_access_local_input; reg [7:0] serial_data_to_write; wire sieze_serial_tx; reg serial_tx_strobe = 0; wire serial_data_received; wire serial_rx_strobe; wire [5:0] lcd_data_in_address; wire [7:0] lcd_data_in_data; wire lcd_data_in_enable; wire [7:0] led_segment_bus; wire [3:0] led_digit_select; //------------------------------------------------------------------------------------------------------- // // Generate a 50MHz clock for the remote access module // //------------------------------------------------------------------------------------------------------- reg main_fifty_clock = 0; always @(posedge clk) begin main_fifty_clock = !main_fifty_clock; end //------------------------------------------------------------------------------------------------------- // // Generate a 25MHz clock for the user progam // //------------------------------------------------------------------------------------------------------- reg clk_div_by_two = 0; always @(posedge main_fifty_clock) begin clk_div_by_two = !clk_div_by_two; end //------------------------------------------------------------------------------------------------------- // // Remote Access Module // // Inputs: // .clk: 50MHz clock // .four_bit_input 4-bit input to the user program from the remote access module // .eight_bit_input 8-bit input to the user program from the remote access module // .sixteen_bit_input 16-bit input to the user program from the remote access module // .serial_port_receiver Input from the serial port's RxD (receive data) pin // .remote_access_input_enable Toggle remote access input vs. local input mode // .local_input Local input to the remote program // .seize_serial_tx Sieze control of the serial transmitter from the remote control system // .serial_tx_data Byte to be transmitted on transmit strobe if control has been siezed // .serial_tx_strobe Transmit serial data on posedge if transmit control has been siezed // .lcd_data_in_address LCD character address (0-32) to write character code to // .lcd_data_in_data LCD character code to write to the address specified // .lcd_data_in_enable Enable LCD data write // .sram_wren_in Synchronous SRAM write enable (1=write, 0=read) // .sram_clock_in Synchronous SRAM clock input // .sram_data_in Synchronous SRAM data input (8-bit) // .sram_address_in Synchronous SRAM address input (14-bit by default) // .sram_processing_done When 1, signal release of user control of synchronous SRAM // .led_segment_bus Connect directly to the 8 bits controlling the LED display segments // .led_digit_select Connect directly to the 4 bits enabling the LED display digits // // Outputs: // .four_bit_output 4-bit output from the user program to the remote access module // .eight_bit_output 8-bit output from the user program to the remote access module // .sixteen_bit_output 16-bit output from the user program to the remote access module // .lcd_data_out Data output to the LCD // .lcd_rs_out RS signal output to the LCD // .lcd_rw_out RW signal output to the LCD // .lcd_enable_out ENABLE signal output to the LCD // .serial_port_transmitter Output to the serial port's TxD (transmit data) pin // .serial_rx_data The last received serial data // .serial_rx_strobe Recevied serial data valid while this signal is 1 // .sram_data_out Synchronous SRAM data output (8-bit) // .sram_available Synchronous SRAM under user control // //------------------------------------------------------------------------------------------------------- wire sram_wren_in; wire sram_clock_in; wire [7:0] sram_data_in; wire [(RAM_ADDR_BITS-1):0] sram_address_in; wire [7:0] sram_data_out; wire sram_available; wire sram_processing_done; // Uncomment this block if no image processing module is provided // assign sram_wren_in = 0; // assign sram_data_in = 0; // assign sram_address_in = 0; // assign sram_processing_done = 1; assign sram_clock_in = main_fifty_clock; remote_access #(RAM_ADDR_BITS) remote_access(.main_fifty_clock(main_fifty_clock), .remote_access_4_bit_output(four_bit_output), .remote_access_4_bit_input(four_bit_input), .remote_access_8_bit_output(eight_bit_output), .remote_access_8_bit_input(eight_bit_input), .remote_access_16_bit_output(sixteen_bit_output), .remote_access_16_bit_input(sixteen_bit_input), .serial_port_receiver(serial_input), .serial_port_transmitter(serial_output), .remote_access_input_enable(btn_center), .local_input(remote_access_local_input), .seize_serial_tx(sieze_serial_tx), .serial_tx_data(serial_data_to_write), .serial_tx_strobe(serial_tx_strobe), .serial_rx_data(serial_data_received), .serial_rx_strobe(serial_rx_strobe), .lcd_data_in_address(lcd_data_in_address), .lcd_data_in_data(lcd_data_in_data), .lcd_data_in_enable(lcd_data_in_enable), .sram_wren_in(sram_wren_in), .sram_clock_in(sram_clock_in), .sram_data_in(sram_data_in), .sram_address_in(sram_address_in), .sram_data_out(sram_data_out), .sram_available(sram_available), .sram_processing_done(sram_processing_done), .led_segment_bus(led_segment_bus), .led_digit_select(led_digit_select)); assign remote_access_local_input[7:4] = 0; // Local inputs assign remote_access_local_input[3:0] = 0; // Local inputs assign led_bank = eight_bit_input; // Mirror input to the LEDs assign sieze_serial_tx = 0; // Allow the remote control module to use the serial port // If the user module must access the serial port directly, delete // this assign statement and control this wire with your module. //------------------------------------------------------------------------------------------------------- // // User Module Instantiation // // Instantiate the simple user module to display remote access input values on the LEDs and to feed // button presses to the remote access module. The 16-bit remote access lines are in loopback. // Feel free to delete this instantiation and the module below to replace it with your module. // //------------------------------------------------------------------------------------------------------- sample_demo sample_demo(.clk(clk_div_by_two), .four_bit_input(four_bit_input), .four_bit_output(four_bit_output), .eight_bit_input(eight_bit_input), .eight_bit_output(eight_bit_output), .sixteen_bit_input(sixteen_bit_input), .sixteen_bit_output(sixteen_bit_output), .lcd_data_in_address(lcd_data_in_address), .lcd_data_in_data(lcd_data_in_data), .lcd_data_in_enable(lcd_data_in_enable), .led_segment_bus(led_segment_bus), .led_digit_select(led_digit_select)); //------------------------------------------------------------------------------------------------------- // // User Image Processing Module Instantiation // // Instantiate the simple userimage processing module to invert the bits in any images sent to the FPGA // //------------------------------------------------------------------------------------------------------- sample_image_processing_demo sample_image_processing_demo(.clk(clk_div_by_two), .wren(sram_wren_in), .dout(sram_data_in), .addr(sram_address_in), .din(sram_data_out), .enable(sram_available), .done(sram_processing_done)); endmodule //------------------------------------------------------------------------------------------------------- // // Demo User Module // //------------------------------------------------------------------------------------------------------- module sample_demo(clk, four_bit_input, four_bit_output, eight_bit_input, eight_bit_output, sixteen_bit_input, sixteen_bit_output, lcd_data_in_address, lcd_data_in_data, lcd_data_in_enable, led_segment_bus, led_digit_select); input clk; input [3:0] four_bit_input; output reg [3:0] four_bit_output; input [7:0] eight_bit_input; output reg [7:0] eight_bit_output; input [15:0] sixteen_bit_input; output reg [15:0] sixteen_bit_output; output reg [5:0] lcd_data_in_address; output reg [7:0] lcd_data_in_data; output reg lcd_data_in_enable; output reg [7:0] led_segment_bus; output reg [3:0] led_digit_select; reg [7:0] lcd_sample_counter = 48; // Create a sample LCD display counter register reg [31:0] lcd_character_change_timer = 0; // Wait a certain number of cycles before loading a new character reg [5:0] lcd_current_character = 0; // The current character's address always @(posedge clk) begin four_bit_output = four_bit_input; // Loopback eight_bit_output = eight_bit_input[3:0] + eight_bit_input[7:4]; // Sample adder sixteen_bit_output = sixteen_bit_input[15:8] * sixteen_bit_input[7:0]; // Sample multiplier // Sample LCD display routine lcd_data_in_address = lcd_current_character; // Character location on the LCD display lcd_data_in_data = lcd_sample_counter; // Character code to display lcd_data_in_enable = 1; // Enable data transmission // Cycle through all character positions lcd_current_character = lcd_current_character + 1; if (lcd_current_character > 31) begin lcd_current_character = 16; end // Cycle through the numbers 0 to 9 at one second intervals lcd_character_change_timer = lcd_character_change_timer + 1; if (lcd_character_change_timer > 25000000) begin // Wait one second in between character changes lcd_character_change_timer = 0; lcd_sample_counter = lcd_sample_counter + 1; if (lcd_sample_counter > 57) begin // Character code for the digit 9 lcd_sample_counter = 48; // Character code for the digit 0 end end end // 7-segment LED display driver clock generator reg sseg_clock; reg [4:0] sseg_clock_counter; always @(posedge clk) begin sseg_clock_counter = sseg_clock_counter + 1; if (sseg_clock_counter > 16) begin sseg_clock_counter = 0; sseg_clock = ~sseg_clock; end end // 7-segment LED display driver // led_segment_bus and led_digit_select are active low // The bit sequence, MSB to LSB, is dp a b c d e f g // Segment letters are taken from ug130.pdf page 15 // 0: 8'b10000001 // 1: 8'b11001111 // 2: 8'b10010010 // 3: 8'b10000110 reg [2:0] current_anode; always @(posedge sseg_clock) begin current_anode = current_anode + 1; if (current_anode > 3) begin current_anode = 0; end case (current_anode) 0: begin led_digit_select = 4'b1110; led_segment_bus = 8'b10000001; end 1: begin led_digit_select = 4'b1101; led_segment_bus = 8'b11001111; end 2: begin led_digit_select = 4'b1011; led_segment_bus = 8'b10010010; end 3: begin led_digit_select = 4'b0111; led_segment_bus = 8'b10000110; end endcase end endmodule //------------------------------------------------------------------------------------------------------- // // Demo User Image Processing Module // //------------------------------------------------------------------------------------------------------- module sample_image_processing_demo(clk, wren, dout, addr, din, enable, done); parameter IMAGE_RAM_ADDR_BITS = 14; input clk; output reg wren; output reg [7:0] dout; output reg [(IMAGE_RAM_ADDR_BITS-1):0] addr; input [7:0] din; input enable; output reg done; reg prev_enable; reg [IMAGE_RAM_ADDR_BITS:0] counter; reg toggler; always @(posedge clk) begin if ((enable == 1) && (prev_enable == 0)) begin counter = 0; toggler = 0; end if ((enable == 1) && (done == 0)) begin if (toggler == 0) begin wren = 0; addr = counter; toggler = 1; end else begin dout = ~din; wren = 1; addr = counter; counter = counter + 1; if (counter > (2**IMAGE_RAM_ADDR_BITS)) begin done = 1; end toggler = 0; end end if (enable == 0) begin done = 0; addr = 0; toggler = 0; end prev_enable = enable; end endmodule