From 04ab7c66320d2f4601626c3018e4ac9fceb4a75c Mon Sep 17 00:00:00 2001 From: Timothy Pearson Date: Thu, 9 Jan 2014 21:16:28 -0600 Subject: Add initial GOMC compatible uLab debug system hardware design files --- fpga/common/remote_access.v | 1253 -------------------- .../xilinx/numato/spartan6/xc6slx9/data_storage.v | 33 + .../numato/spartan6/xc6slx9/lcd_data_storage.v | 44 + fpga/gpmc/xilinx/numato/spartan6/xc6slx9/main.ucf | 128 ++ fpga/gpmc/xilinx/numato/spartan6/xc6slx9/main.v | 393 ++++++ .../spartan6/xc6slx9/ulab_debug_interface.xise | 409 +++++++ fpga/serial/common/remote_access.v | 1253 ++++++++++++++++++++ .../xilinx/digilent/spartan_3/remote_access.v | 1 + .../xilinx/digilent/spartan_3e/remote_access.v | 1 + .../xilinx/digilent/spartan_6/remote_access.v | 1 + .../spartan_6/s6_remotefpga_test/data_storage.v | 33 + .../digilent/spartan_6/s6_remotefpga_test/main.ucf | 8 + .../digilent/spartan_6/s6_remotefpga_test/main.v | 330 ++++++ .../spartan_6/s6_remotefpga_test/remote_access.v | 1 + .../s6_remotefpga_test/s6_remotefpga_test.xise | 366 ++++++ fpga/xilinx/digilent/spartan_3/remote_access.v | 1 - fpga/xilinx/digilent/spartan_3e/remote_access.v | 1 - fpga/xilinx/digilent/spartan_6/remote_access.v | 1 - .../spartan_6/s6_remotefpga_test/data_storage.v | 33 - .../digilent/spartan_6/s6_remotefpga_test/main.ucf | 8 - .../digilent/spartan_6/s6_remotefpga_test/main.v | 330 ------ .../spartan_6/s6_remotefpga_test/remote_access.v | 1 - .../s6_remotefpga_test/s6_remotefpga_test.xise | 366 ------ 23 files changed, 3001 insertions(+), 1994 deletions(-) delete mode 100644 fpga/common/remote_access.v create mode 100644 fpga/gpmc/xilinx/numato/spartan6/xc6slx9/data_storage.v create mode 100644 fpga/gpmc/xilinx/numato/spartan6/xc6slx9/lcd_data_storage.v create mode 100644 fpga/gpmc/xilinx/numato/spartan6/xc6slx9/main.ucf create mode 100644 fpga/gpmc/xilinx/numato/spartan6/xc6slx9/main.v create mode 100644 fpga/gpmc/xilinx/numato/spartan6/xc6slx9/ulab_debug_interface.xise create mode 100644 fpga/serial/common/remote_access.v create mode 120000 fpga/serial/xilinx/digilent/spartan_3/remote_access.v create mode 120000 fpga/serial/xilinx/digilent/spartan_3e/remote_access.v create mode 120000 fpga/serial/xilinx/digilent/spartan_6/remote_access.v create mode 100644 fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/data_storage.v create mode 100644 fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf create mode 100644 fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v create mode 120000 fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/remote_access.v create mode 100644 fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/s6_remotefpga_test.xise delete mode 120000 fpga/xilinx/digilent/spartan_3/remote_access.v delete mode 120000 fpga/xilinx/digilent/spartan_3e/remote_access.v delete mode 120000 fpga/xilinx/digilent/spartan_6/remote_access.v delete mode 100644 fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/data_storage.v delete mode 100644 fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf delete mode 100644 fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v delete mode 120000 fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/remote_access.v delete mode 100644 fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/s6_remotefpga_test.xise diff --git a/fpga/common/remote_access.v b/fpga/common/remote_access.v deleted file mode 100644 index 5a37e86..0000000 --- a/fpga/common/remote_access.v +++ /dev/null @@ -1,1253 +0,0 @@ -`timescale 1ns / 1ps -////////////////////////////////////////////////////////////////////////////////// -// Company: Raptor Engineering -// Engineer: Timothy Pearson -// -// Design Name: Remote Access Driver -// Module Name: remote_access -// Project Name: Remote Access Driver -// Target Devices: Any -// Description: Serial remote access driver and LCD display driver -// -// Dependencies: -// -// (c) 2007-2013 Timothy Pearson, Raptor Engineering -// Released into the Public Domain -// -////////////////////////////////////////////////////////////////////////////////// -module remote_access( - input main_fifty_clock, // 50MHz clock in - input [3:0] remote_access_4_bit_output, // 4 bit output from the user program to remote access client - output [3:0] remote_access_4_bit_input, // 4 bit input from the remote access client to user program - input [7:0] remote_access_8_bit_output, // 8 bit output from the user program to remote access client - output [7:0] remote_access_8_bit_input, // 8 bit input from the remote access client to user program - input [15:0] remote_access_16_bit_output, // 16 bit output from the user program to the remote access client - output [15:0] remote_access_16_bit_input, // 16 bit input from the remote access client to the user program - input serial_port_receiver, - output serial_port_transmitter, - input remote_access_input_enable, - input [7:0] local_input, - input seize_serial_tx, - input [7:0] serial_tx_data, - input serial_tx_strobe, - output [7:0] serial_rx_data, - output serial_rx_strobe, - input [5:0] lcd_data_in_address, - input [7:0] lcd_data_in_data, - input lcd_data_in_enable, - input sram_wren_in, - input sram_clock_in, - input [7:0] sram_data_in, - input [(RAM_ADDR_BITS-1):0] sram_address_in, - output [7:0] sram_data_out, - output sram_available, - input sram_processing_done, - input [7:0] led_segment_bus, - input [3:0] led_digit_select, - - // For use on Digilent Spartan 3E or compatible board only - output [3:0] remote_access_lcd_data_out, - output remote_access_lcd_rs_out, - output remote_access_lcd_rw_out, - output remote_access_lcd_enable_out); - - parameter RAM_ADDR_BITS = 14; - - reg [7:0] remote_access_4_bit_input_reg; - reg [7:0] remote_access_8_bit_input_reg; - reg [15:0] remote_access_16_bit_input_reg; - reg [3:0] remote_access_lcd_data_out_reg; - reg remote_access_lcd_rs_out_reg; - reg remote_access_lcd_rw_out_reg; - reg remote_access_lcd_enable_out_reg; - reg [7:0] serial_rx_data_reg; - reg serial_rx_strobe_reg; - reg sram_available_reg; - reg startup_needed = 1; - - assign remote_access_4_bit_input = remote_access_4_bit_input_reg[3:0]; - assign remote_access_8_bit_input = remote_access_8_bit_input_reg; - assign remote_access_16_bit_input = remote_access_16_bit_input_reg; - assign remote_access_lcd_data_out = remote_access_lcd_data_out_reg; - assign remote_access_lcd_rs_out = remote_access_lcd_rs_out_reg; - assign remote_access_lcd_rw_out = remote_access_lcd_rw_out_reg; - assign remote_access_lcd_enable_out = remote_access_lcd_enable_out_reg; - assign serial_rx_data = serial_rx_data_reg; - assign serial_rx_strobe = serial_rx_strobe_reg; - assign sram_available = sram_available_reg; - - //----------------------------------------------------------------------------------- - // - // Create a 4.16MHz clock for the LCD display driver and a 25MHz clock - // for the serial receiver. - // - //----------------------------------------------------------------------------------- - - reg four_mhz_clk; - reg clk_div_by_two; - reg clk_div_by_two_oneeighty; - reg clk_div_by_four; - reg clk_div_by_eight; - reg [3:0] fifty_clock_divider = 0; - - always @(posedge main_fifty_clock) begin - fifty_clock_divider = fifty_clock_divider + 1; - if (fifty_clock_divider > 12) begin - four_mhz_clk = !four_mhz_clk; - fifty_clock_divider = 0; - end - end - - always @(posedge main_fifty_clock) begin - clk_div_by_two = !clk_div_by_two; - end - - always @(negedge main_fifty_clock) begin - clk_div_by_two_oneeighty = !clk_div_by_two_oneeighty; - end - - always @(posedge clk_div_by_two_oneeighty) begin - clk_div_by_four = !clk_div_by_four; - end - - always @(posedge clk_div_by_four) begin - clk_div_by_eight = !clk_div_by_eight; - end - - //----------------------------------------------------------------------------------- - // - // Keep track of what is on the LED display - // - //----------------------------------------------------------------------------------- - - reg [7:0] led_display_bytes [3:0]; - reg [17:0] digit_blanker_1 = 0; - reg [17:0] digit_blanker_2 = 0; - reg [17:0] digit_blanker_3 = 0; - reg [17:0] digit_blanker_4 = 0; - - reg [7:0] led_segment_bus_latch; - reg [3:0] led_digit_select_latch; - - always @(negedge clk_div_by_eight) begin - led_segment_bus_latch = led_segment_bus; - led_digit_select_latch = led_digit_select; - - if (led_digit_select_latch[0] == 0) begin - led_display_bytes[0] = led_segment_bus_latch; - digit_blanker_1 = 0; - digit_blanker_2 = digit_blanker_2 + 1; - digit_blanker_3 = digit_blanker_3 + 1; - digit_blanker_4 = digit_blanker_4 + 1; - end - - if (led_digit_select_latch[1] == 0) begin - led_display_bytes[1] = led_segment_bus_latch; - digit_blanker_1 = digit_blanker_1 + 1; - digit_blanker_2 = 0; - digit_blanker_3 = digit_blanker_3 + 1; - digit_blanker_4 = digit_blanker_4 + 1; - end - - if (led_digit_select_latch[2] == 0) begin - led_display_bytes[2] = led_segment_bus_latch; - digit_blanker_1 = digit_blanker_1 + 1; - digit_blanker_2 = digit_blanker_2 + 1; - digit_blanker_3 = 0; - digit_blanker_4 = digit_blanker_4 + 1; - end - - if (led_digit_select_latch[3] == 0) begin - led_display_bytes[3] = led_segment_bus_latch; - digit_blanker_1 = digit_blanker_1 + 1; - digit_blanker_2 = digit_blanker_2 + 1; - digit_blanker_3 = digit_blanker_3 + 1; - digit_blanker_4 = 0; - end - - if (digit_blanker_1 > 128000) begin - led_display_bytes[0] = 255; - end - - if (digit_blanker_2 > 128000) begin - led_display_bytes[1] = 255; - end - - if (digit_blanker_3 > 128000) begin - led_display_bytes[2] = 255; - end - - if (digit_blanker_4 > 128000) begin - led_display_bytes[3] = 255; - end - end - - //----------------------------------------------------------------------------------- - // - // Instantiate the data storage RAM for signal processing - // - //----------------------------------------------------------------------------------- - - reg data_storage_remote_enable = 0; - wire data_storage_clka; - wire [7:0] data_storage_dina; - wire [(RAM_ADDR_BITS-1):0] data_storage_addra; - wire data_storage_write_enable; - wire [7:0] data_storage_data_out; - - reg [7:0] data_storage_dina_reg; - reg [(RAM_ADDR_BITS-1):0] data_storage_addra_reg; - reg data_storage_write_enable_reg; - - data_storage #(RAM_ADDR_BITS) data_storage(.clka(data_storage_clka), .dina(data_storage_dina), .addra(data_storage_addra), - .wea(data_storage_write_enable), .douta(data_storage_data_out)); - - assign data_storage_clka = (data_storage_remote_enable) ? main_fifty_clock : sram_clock_in; - assign data_storage_dina = (data_storage_remote_enable) ? data_storage_dina_reg : sram_data_in; - assign data_storage_addra = (data_storage_remote_enable) ? data_storage_addra_reg : sram_address_in; - assign data_storage_write_enable = (data_storage_remote_enable) ? data_storage_write_enable_reg : sram_wren_in; - - assign sram_data_out = data_storage_data_out; - - // ----------------------------------------------------------------------------------------------- - // - // Here is the serial receiver and transmitter - // - // ----------------------------------------------------------------------------------------------- - - reg [7:0] transmit_all_data_state = 0; - - wire RxD_data_ready; - wire [7:0] RxD_data; - wire RxD_endofpacket; - wire RxD_idle; - - reg TxD_start; - reg [7:0] TxD_data; - wire TxD_busy; - wire [4:0] state; - - reg [7:0] transmitter_4_bit_state = 0; - reg [7:0] transmitter_8_bit_state = 0; - reg [15:0] transmitter_16_bit_state = 0; - reg [7:0] transmitter_main_state = 0; - reg [7:0] transmitter_input_state = 0; - - async_transmit asyncTX(.clk(clk_div_by_two), .TxD_start(TxD_start), .TxD_data(TxD_data), .TxD(serial_port_transmitter), .TxD_busy(TxD_busy), .state(state)); - async_receiver asyncRX(.clk(clk_div_by_two), .RxD(serial_port_receiver), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data), .RxD_endofpacket(RxD_endofpacket), .RxD_idle(RxD_idle)); - - reg tx_toggle = 0; - - reg transmit_4_bit_status = 0; - reg transmit_4_bit_status_done = 0; - - reg transmit_8_bit_status = 0; - reg transmit_8_bit_status_done = 0; - - reg transmit_16_bit_status = 0; - reg transmit_16_bit_pass_two = 0; - reg transmit_16_bit_status_done = 0; - - reg transmit_main_status = 0; - reg transmit_main_status_done = 0; - - reg transmit_dsp_ram_size = 0; - reg transmit_dsp_ram_size_done = 0; - - reg transmit_input_status = 0; - reg transmit_input_status_done = 0; - - reg transmit_lcd_status = 0; - reg transmit_lcd_status_done = 0; - reg [7:0] transmit_lcd_status_counter = 0; - - reg enable_remote_access_input = 1; - reg remote_access_input_enable_prev = 0; - - reg [7:0] lcd_display_string [31:0]; - - reg transmit_dsp_status = 0; - reg transmit_dsp_status_done = 0; - reg transmit_dsp_status_holdoff = 0; - reg [RAM_ADDR_BITS:0] transmit_dsp_status_counter = 0; - - reg transmit_led_status = 0; - reg transmit_led_status_done = 0; - reg [7:0] transmit_led_status_counter = 0; - - reg transmit_dsp_rx_complete = 0; - reg transmit_dsp_rx_complete_done = 0; - - // Transmit! - always @(posedge clk_div_by_two) begin - transmitter_4_bit_state = remote_access_4_bit_output; - transmitter_8_bit_state = remote_access_8_bit_output; - transmitter_16_bit_state = remote_access_16_bit_output; - - transmitter_main_state = 0; - transmitter_main_state[0] = enable_remote_access_input; - - transmitter_input_state = local_input; - - if (seize_serial_tx == 1) begin - TxD_start = serial_tx_strobe; - TxD_data = serial_tx_data; - end else begin - if (tx_toggle == 0) begin - if ((transmit_4_bit_status == 1) && (transmit_4_bit_status_done == 0)) begin - TxD_data = transmitter_4_bit_state; - - TxD_start = 1; - tx_toggle = 1; - - transmit_4_bit_status_done = 1; - end - - if ((transmit_8_bit_status == 1) && (transmit_8_bit_status_done == 0)) begin - TxD_data = transmitter_8_bit_state; - - TxD_start = 1; - tx_toggle = 1; - - transmit_8_bit_status_done = 1; - end - - if ((transmit_16_bit_status == 1) && (transmit_16_bit_status_done == 0)) begin - if (transmit_16_bit_pass_two == 0) begin - TxD_data = transmitter_16_bit_state[15:8]; - - TxD_start = 1; - tx_toggle = 1; - - transmit_16_bit_pass_two = 1; - end else begin - TxD_data = transmitter_16_bit_state[7:0]; - - TxD_start = 1; - tx_toggle = 1; - - transmit_16_bit_status_done = 1; - end - end - - if ((transmit_main_status == 1) && (transmit_main_status_done == 0)) begin - TxD_data = transmitter_main_state; - - TxD_start = 1; - tx_toggle = 1; - - transmit_main_status_done = 1; - end - - if ((transmit_dsp_ram_size == 1) && (transmit_dsp_ram_size_done == 0)) begin - TxD_data = RAM_ADDR_BITS; - - TxD_start = 1; - tx_toggle = 1; - - transmit_dsp_ram_size_done = 1; - end - - if ((transmit_input_status == 1) && (transmit_input_status_done == 0)) begin - TxD_data = transmitter_input_state; - - TxD_start = 1; - tx_toggle = 1; - - transmit_input_status_done = 1; - end - - if ((transmit_lcd_status == 1) && (transmit_lcd_status_done == 0)) begin - TxD_data = lcd_display_string[transmit_lcd_status_counter]; - - TxD_start = 1; - tx_toggle = 1; - - transmit_lcd_status_counter = transmit_lcd_status_counter + 1; - if (transmit_lcd_status_counter > 31) begin - transmit_lcd_status_done = 1; - end - end - - if ((transmit_led_status == 1) && (transmit_led_status_done == 0)) begin - TxD_data = led_display_bytes[transmit_led_status_counter]; - - TxD_start = 1; - tx_toggle = 1; - - transmit_led_status_counter = transmit_led_status_counter + 1; - if (transmit_led_status_counter > 3) begin - transmit_led_status_done = 1; - end - end - - if ((transmit_dsp_rx_complete == 1) && (transmit_dsp_rx_complete_done == 0)) begin - TxD_data = 77; - - TxD_start = 1; - tx_toggle = 1; - - transmit_dsp_rx_complete_done = 1; - end - - if ((transmit_dsp_status == 1) && (transmit_dsp_rx_complete == 0) && (transmit_dsp_status_done == 0)) begin - if (transmit_dsp_status_holdoff == 0) begin - transmit_dsp_status_holdoff = 1; - data_storage_write_enable_reg = 0; - data_storage_addra_reg = 0; // Initial data value - end else begin - data_storage_write_enable_reg = 0; - TxD_data = data_storage_data_out; - - TxD_start = 1; - tx_toggle = 1; - - transmit_dsp_status_counter = transmit_dsp_status_counter + 1; - data_storage_addra_reg = transmit_dsp_status_counter[(RAM_ADDR_BITS-1):0]; - if (transmit_dsp_status_counter >= (2**RAM_ADDR_BITS)) begin - transmit_dsp_status_done = 1; - data_storage_write_enable_reg = 1'bz; - data_storage_addra_reg = {(RAM_ADDR_BITS){1'bz}}; - end - end - end - end else begin - if (state == 5'b10000) begin // Wait for transmission of byte to complete - TxD_start = 0; - tx_toggle = 0; - end - end - end - - if (transmit_4_bit_status == 0) begin - transmit_4_bit_status_done = 0; - end - - if (transmit_8_bit_status == 0) begin - transmit_8_bit_status_done = 0; - end - - if (transmit_16_bit_status == 0) begin - transmit_16_bit_pass_two = 0; - transmit_16_bit_status_done = 0; - end - - if (transmit_main_status == 0) begin - transmit_main_status_done = 0; - end - - if (transmit_dsp_ram_size == 0) begin - transmit_dsp_ram_size_done = 0; - end - - if (transmit_input_status == 0) begin - transmit_input_status_done = 0; - end - - if (transmit_lcd_status == 0) begin - transmit_lcd_status_done = 0; - transmit_lcd_status_counter = 0; - end - - if (transmit_led_status == 0) begin - transmit_led_status_done = 0; - transmit_led_status_counter = 0; - end - - if (transmit_dsp_rx_complete == 0) begin - transmit_dsp_rx_complete_done = 0; - end - - if (transmit_dsp_status == 0) begin - transmit_dsp_status_done = 0; - transmit_dsp_status_holdoff = 0; - transmit_dsp_status_counter = 0; - end - end - - reg [7:0] lcd_display_initialization_state = 0; - reg serial_character_received = 0; - reg [7:0] serial_receiver_toggler = 0; - reg [7:0] serial_command_buffer = 0; - reg [2:0] next_byte_is_command = 0; - reg [7:0] next_byte_is_command_prev_command = 0; - reg [7:0] serial_command_timer = 0; - reg update_lcd_display = 0; - reg [7:0] serial_update_counter = 0; - reg [RAM_ADDR_BITS:0] dsp_update_counter = 0; - reg [7:0] received_lcd_display_string [31:0]; - reg data_write_timer = 0; - reg waiting_on_dsp_processing = 0; - - // Receive serial commands - always @(posedge clk_div_by_two) begin - if (startup_needed == 1) begin - startup_needed = 0; - transmit_dsp_status = 1; - end - - if (lcd_data_in_enable == 1) begin - received_lcd_display_string[lcd_data_in_address] = lcd_data_in_data; - update_lcd_display = 1; - serial_command_timer = 255; - end - - if ((remote_access_input_enable == 1) && (remote_access_input_enable_prev == 0)) begin - enable_remote_access_input = !enable_remote_access_input; - end - remote_access_input_enable_prev = remote_access_input_enable; - - if (enable_remote_access_input == 0) begin - // Enable local input - remote_access_8_bit_input_reg = local_input; - end - - if (serial_command_timer > 0) begin - serial_command_timer = serial_command_timer - 1; - end else begin - update_lcd_display = 0; - end - - if (transmit_4_bit_status_done == 1) begin - transmit_4_bit_status = 0; - if (transmit_all_data_state == 1) begin - transmit_8_bit_status = 1; - end - end - - if (transmit_8_bit_status_done == 1) begin - transmit_8_bit_status = 0; - if (transmit_all_data_state == 1) begin - transmit_16_bit_status = 1; - end - end - - if (transmit_16_bit_status_done == 1) begin - transmit_16_bit_status = 0; - if (transmit_all_data_state == 1) begin - transmit_led_status = 1; - end - end - - if (transmit_led_status_done == 1) begin - transmit_led_status = 0; - if (transmit_all_data_state == 1) begin - transmit_all_data_state = 0; - end - end - - if (transmit_dsp_rx_complete_done == 1) begin - transmit_dsp_rx_complete = 0; - end - - if (transmit_main_status_done == 1) begin - transmit_main_status = 0; - if (transmit_all_data_state == 1) begin - transmit_dsp_ram_size = 1; - end - end - - if (transmit_dsp_ram_size_done == 1) begin - transmit_dsp_ram_size = 0; - if (transmit_all_data_state == 1) begin - transmit_4_bit_status = 1; - end - end - - if (transmit_input_status_done == 1) begin - transmit_input_status = 0; - end - - if (transmit_lcd_status_done == 1) begin - transmit_lcd_status = 0; - if (transmit_all_data_state == 1) begin - transmit_main_status = 1; - end - end - - if (transmit_dsp_status_done == 1) begin - transmit_dsp_status = 0; - data_storage_remote_enable = 0; - end - - if (transmit_dsp_status == 1) begin - data_storage_remote_enable = 1; - end - - if (data_write_timer > 1) begin - data_write_timer = data_write_timer - 1; - end else begin - if (data_write_timer == 1) begin - data_storage_write_enable_reg = 0; - data_write_timer = 0; - end - end - - if ((waiting_on_dsp_processing == 1) && (sram_processing_done == 1)) begin - waiting_on_dsp_processing = 0; - transmit_dsp_status = 1; - end - - serial_rx_strobe_reg = 0; // Make sure that this get reset! - - if ((sram_processing_done == 1) && (sram_available_reg == 1)) begin - sram_available_reg = 0; - transmit_dsp_status = 1; - end - - if (RxD_data_ready == 1) begin - if (serial_character_received == 0) begin - serial_rx_data_reg = RxD_data; - serial_rx_strobe_reg = 1; // Signal new data... - if (seize_serial_tx == 0) begin - if (next_byte_is_command_prev_command == 77) begin - // DSP input data - if (dsp_update_counter < (2**RAM_ADDR_BITS)) begin - data_storage_remote_enable = 1; - data_storage_addra_reg = dsp_update_counter[(RAM_ADDR_BITS-1):0]; - data_storage_dina_reg = serial_rx_data_reg; - data_storage_write_enable_reg = 1; - data_write_timer = 3; - dsp_update_counter = dsp_update_counter + 1; - - // TESTING ONLY!!! - //if (dsp_update_counter < 17) begin - // received_lcd_display_string[dsp_update_counter - 1] = serial_command_buffer; - //end - - if (dsp_update_counter >= (2**RAM_ADDR_BITS)) begin - next_byte_is_command = 0; - data_storage_write_enable_reg = 0; - data_storage_remote_enable = 0; - sram_available_reg = 1; - data_storage_write_enable_reg = 1'bz; - data_storage_addra_reg = {(RAM_ADDR_BITS){1'bz}}; - waiting_on_dsp_processing = 1; - transmit_dsp_rx_complete = 1; - next_byte_is_command_prev_command = 0; - - // TESTING ONLY!!! - //transmit_dsp_status = 1; - end - end - end else begin - // Parse the command and see what it is - serial_character_received = 1; - if (serial_rx_data_reg == 13) begin - // Carriage Return! The serial_command_buffer holds the command! Parse it! - if (next_byte_is_command == 0) begin - if (serial_command_buffer == 65) begin - // Display update requested - next_byte_is_command = 1; - serial_update_counter = 0; - next_byte_is_command_prev_command = 65; - end - - if (serial_command_buffer == 66) begin - // 8 bit input update - if (enable_remote_access_input == 1) begin - next_byte_is_command = 1; - serial_update_counter = 0; - next_byte_is_command_prev_command = 66; - end - end - - if (serial_command_buffer == 67) begin - // 16 bit input update - next_byte_is_command = 1; - serial_update_counter = 0; - next_byte_is_command_prev_command = 67; - end - - if (serial_command_buffer == 68) begin - // 8 bit output status - transmit_8_bit_status = 1; - end - - if (serial_command_buffer == 69) begin - // 16 bit output status - transmit_16_bit_status = 1; - end - - if (serial_command_buffer == 70) begin - // System status - transmit_main_status = 1; - end - - if (serial_command_buffer == 71) begin - // Simulate center button press - enable_remote_access_input = !enable_remote_access_input; - end - - if (serial_command_buffer == 72) begin - // Local input status - transmit_input_status = 1; - end - - if (serial_command_buffer == 73) begin - // 4 bit input update - if (enable_remote_access_input == 1) begin - next_byte_is_command = 1; - serial_update_counter = 0; - next_byte_is_command_prev_command = 73; - end - end - - if (serial_command_buffer == 74) begin - // 4 bit output status - transmit_4_bit_status = 1; - end - - if (serial_command_buffer == 75) begin - // Transmit the contents of the LCD... - transmit_lcd_status = 1; - end - - if (serial_command_buffer == 76) begin - // Transmit the contents of the LCD... - transmit_all_data_state = 1; - transmit_lcd_status = 1; - end - - if (serial_command_buffer == 77) begin - // Receive offline DSP data - next_byte_is_command = 1; - dsp_update_counter = 0; - next_byte_is_command_prev_command = 77; - end - - if (serial_command_buffer == 78) begin - // Transmit the contents of RAM... - transmit_dsp_status = 1; - end - - if (serial_command_buffer == 79) begin - // Transmit the DSP RAM size - transmit_dsp_ram_size = 1; - end - end else begin - if (next_byte_is_command == 1) begin - // The previous byte was the command--now load in the data! - if (next_byte_is_command_prev_command == 65) begin - if (serial_update_counter < 32) begin - received_lcd_display_string[serial_update_counter] = serial_command_buffer; - serial_update_counter = serial_update_counter + 1; - end else begin - update_lcd_display = 1; - serial_command_timer = 255; - next_byte_is_command = 0; - end - end - - // 4 bit input update - if (next_byte_is_command_prev_command == 73) begin - remote_access_4_bit_input_reg = serial_command_buffer; - next_byte_is_command = 0; - end - - // 8 bit input update - if (next_byte_is_command_prev_command == 66) begin - remote_access_8_bit_input_reg = serial_command_buffer; - next_byte_is_command = 0; - end - - // 16 bit input update - if (next_byte_is_command_prev_command == 67) begin - if (serial_update_counter == 0) begin - remote_access_16_bit_input_reg[15:8] = serial_command_buffer; - serial_update_counter = 1; - end else begin - remote_access_16_bit_input_reg[7:0] = serial_command_buffer; - next_byte_is_command = 0; - end - end - end - end - end - end - end - - //if (RxD_data != 10) begin // Ignore linefeeds - serial_command_buffer = RxD_data; - //end - - serial_receiver_toggler = serial_receiver_toggler + 1; - end - end - - if (RxD_data_ready == 0) begin - serial_character_received = 0; - end - end - - //----------------------------------------------------------------------------------- - // - // This routine will display the contents of lcd_display_string on the LCD display - // - //----------------------------------------------------------------------------------- - - reg [15:0] lcd_display_wait_counter = 0; - reg [7:0] lcd_display_current_character = 0; - reg lcd_display_line_two = 0; // Are we trying to write to line two? - - always @(posedge four_mhz_clk) begin - case (lcd_display_initialization_state) - // Initialize the display according to the reference manual - 0:begin - // Set up the default display... - lcd_display_string[0] = 73; // I - lcd_display_string[1] = 110; // n - lcd_display_string[2] = 105; // i - lcd_display_string[3] = 116; // t - lcd_display_string[4] = 105; // i - lcd_display_string[5] = 97; // a - lcd_display_string[6] = 108; // l - lcd_display_string[7] = 105; // i - lcd_display_string[8] = 122; // z - lcd_display_string[9] = 97; // a - lcd_display_string[10] = 116; // t - lcd_display_string[11] = 105; // i - lcd_display_string[12] = 111; // o - lcd_display_string[13] = 110; // n - lcd_display_string[14] = 32; // - lcd_display_string[15] = 32; // - lcd_display_string[16] = 79; // O - lcd_display_string[17] = 75; // k - lcd_display_string[18] = 32; // - lcd_display_string[19] = 32; // - lcd_display_string[20] = 32; // - lcd_display_string[21] = 32; // - lcd_display_string[22] = 32; // - lcd_display_string[23] = 32; // - lcd_display_string[24] = 32; // - lcd_display_string[25] = 32; // - lcd_display_string[26] = 32; // - lcd_display_string[27] = 32; // - lcd_display_string[28] = 32; // - lcd_display_string[29] = 32; // - lcd_display_string[30] = 32; // - lcd_display_string[31] = 32; // - - lcd_display_current_character = 0; - - lcd_display_line_two = 0; - remote_access_lcd_data_out_reg = 3; - remote_access_lcd_enable_out_reg = 1; - remote_access_lcd_rs_out_reg = 0; - remote_access_lcd_rw_out_reg = 0; - lcd_display_wait_counter = 17083; // Wait 15mS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 1:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 2:begin - remote_access_lcd_data_out_reg = 3; - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 417; // Wait 100uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 3:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 4:begin - remote_access_lcd_data_out_reg = 3; - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 167; // Wait 40uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 5:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 6:begin - remote_access_lcd_data_out_reg = 2; - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 167; // Wait 40uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 7:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - // Display is now initialized - - // Send Function Set command - 8:begin - remote_access_lcd_data_out_reg = 2; - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 5; // Wait 1uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 9:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 10:begin - remote_access_lcd_data_out_reg = 8; - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 167; // Wait 40uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 11:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - - // Send Entry Mode Set command - 12:begin - remote_access_lcd_data_out_reg = 0; - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 5; // Wait 1uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 13:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 14:begin - remote_access_lcd_data_out_reg = 6; - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 167; // Wait 40uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 15:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - - // Send Display On command and disable cursors and blinking - 16:begin - remote_access_lcd_data_out_reg = 0; - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 5; // Wait 1uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 17:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 18:begin - remote_access_lcd_data_out_reg = 12; - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 167; // Wait 40uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 19:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - - // Send Clear Display command - 20:begin - remote_access_lcd_data_out_reg = 0; - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 5; // Wait 1uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 21:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 22:begin - remote_access_lcd_data_out_reg = 1; - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 6833; // Wait 1.64uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 23:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - - // Set DD RAM Address to 0 if lcd_display_line_two is 0, or 0x40 if it is 1 - 24:begin - remote_access_lcd_rs_out_reg = 0; - if (lcd_display_line_two == 0) begin - remote_access_lcd_data_out_reg = 8; - end - if (lcd_display_line_two == 1) begin - remote_access_lcd_data_out_reg = 12; - end - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 5; // Wait 1uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 25:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 26:begin - remote_access_lcd_data_out_reg = 0; - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 167; // Wait 40uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 27:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - - // Display the characters - 28:begin - remote_access_lcd_data_out_reg = lcd_display_string[lcd_display_current_character][7:4]; - remote_access_lcd_rs_out_reg = 1; - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 5; // Wait 1uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 29:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 30:begin - remote_access_lcd_data_out_reg = lcd_display_string[lcd_display_current_character][3:0]; - remote_access_lcd_enable_out_reg = 1; - lcd_display_wait_counter = 167; // Wait 40uS - lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 31:begin - remote_access_lcd_enable_out_reg = 0; - lcd_display_wait_counter = lcd_display_wait_counter - 1; - if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; - end - 32:begin - lcd_display_current_character = lcd_display_current_character + 1; - lcd_display_initialization_state = lcd_display_initialization_state + 1; - if (lcd_display_current_character < 32) begin - lcd_display_initialization_state = 28; - end - if (lcd_display_current_character == 16) begin - if (lcd_display_line_two == 0) begin - lcd_display_line_two = 1; - lcd_display_initialization_state = 24; - end - end - end - 33:begin - // End! - remote_access_lcd_rs_out_reg = 0; - remote_access_lcd_enable_out_reg = 0; - lcd_display_line_two = 0; - lcd_display_current_character = 0; - if (update_lcd_display == 1) begin - lcd_display_line_two = 0; - lcd_display_current_character = 0; - lcd_display_initialization_state = 24; - lcd_display_string[0] = received_lcd_display_string[0]; - lcd_display_string[1] = received_lcd_display_string[1]; - lcd_display_string[2] = received_lcd_display_string[2]; - lcd_display_string[3] = received_lcd_display_string[3]; - lcd_display_string[4] = received_lcd_display_string[4]; - lcd_display_string[5] = received_lcd_display_string[5]; - lcd_display_string[6] = received_lcd_display_string[6]; - lcd_display_string[7] = received_lcd_display_string[7]; - lcd_display_string[8] = received_lcd_display_string[8]; - lcd_display_string[9] = received_lcd_display_string[9]; - lcd_display_string[10] = received_lcd_display_string[10]; - lcd_display_string[11] = received_lcd_display_string[11]; - lcd_display_string[12] = received_lcd_display_string[12]; - lcd_display_string[13] = received_lcd_display_string[13]; - lcd_display_string[14] = received_lcd_display_string[14]; - lcd_display_string[15] = received_lcd_display_string[15]; - lcd_display_string[16] = received_lcd_display_string[16]; - lcd_display_string[17] = received_lcd_display_string[17]; - lcd_display_string[18] = received_lcd_display_string[18]; - lcd_display_string[19] = received_lcd_display_string[19]; - lcd_display_string[20] = received_lcd_display_string[20]; - lcd_display_string[21] = received_lcd_display_string[21]; - lcd_display_string[22] = received_lcd_display_string[22]; - lcd_display_string[23] = received_lcd_display_string[23]; - lcd_display_string[24] = received_lcd_display_string[24]; - lcd_display_string[25] = received_lcd_display_string[25]; - lcd_display_string[26] = received_lcd_display_string[26]; - lcd_display_string[27] = received_lcd_display_string[27]; - lcd_display_string[28] = received_lcd_display_string[28]; - lcd_display_string[29] = received_lcd_display_string[29]; - lcd_display_string[30] = received_lcd_display_string[30]; - lcd_display_string[31] = received_lcd_display_string[31]; - end - end - endcase - end -endmodule - -module async_receiver(clk, RxD, RxD_data_ready, RxD_data, RxD_endofpacket, RxD_idle); - input clk, RxD; - output RxD_data_ready; // onc clock pulse when RxD_data is valid - output [7:0] RxD_data; - - parameter ClkFrequency = 25000000; // 25MHz - parameter Baud = 115200; - - // We also detect if a gap occurs in the received stream of characters - // That can be useful if multiple characters are sent in burst - // so that multiple characters can be treated as a "packet" - output RxD_endofpacket; // one clock pulse, when no more data is received (RxD_idle is going high) - output RxD_idle; // no data is being received - - // Baud generator (we use 8 times oversampling) - parameter Baud8 = Baud*8; - parameter Baud8GeneratorAccWidth = 16; - wire [Baud8GeneratorAccWidth:0] Baud8GeneratorInc = ((Baud8<<(Baud8GeneratorAccWidth-7))+(ClkFrequency>>8))/(ClkFrequency>>7); - reg [Baud8GeneratorAccWidth:0] Baud8GeneratorAcc; - always @(posedge clk) Baud8GeneratorAcc <= Baud8GeneratorAcc[Baud8GeneratorAccWidth-1:0] + Baud8GeneratorInc; - wire Baud8Tick = Baud8GeneratorAcc[Baud8GeneratorAccWidth]; - - //////////////////////////// - reg [1:0] RxD_sync_inv; - always @(posedge clk) if(Baud8Tick) RxD_sync_inv <= {RxD_sync_inv[0], ~RxD}; - // we invert RxD, so that the idle becomes "0", to prevent a phantom character to be received at startup - - reg [1:0] RxD_cnt_inv; - reg RxD_bit_inv; - - always @(posedge clk) - if(Baud8Tick) - begin - if( RxD_sync_inv[1] && RxD_cnt_inv!=2'b11) RxD_cnt_inv <= RxD_cnt_inv + 2'h1; - else - if(~RxD_sync_inv[1] && RxD_cnt_inv!=2'b00) RxD_cnt_inv <= RxD_cnt_inv - 2'h1; - - if(RxD_cnt_inv==2'b00) RxD_bit_inv <= 1'b0; - else - if(RxD_cnt_inv==2'b11) RxD_bit_inv <= 1'b1; - end - - reg [3:0] state; - reg [3:0] bit_spacing; - - // "next_bit" controls when the data sampling occurs - // depending on how noisy the RxD is, different values might work better - // with a clean connection, values from 8 to 11 work - wire next_bit = (bit_spacing==4'd10); - - always @(posedge clk) - if(state==0) - bit_spacing <= 4'b0000; - else - if(Baud8Tick) - bit_spacing <= {bit_spacing[2:0] + 4'b0001} | {bit_spacing[3], 3'b000}; - - always @(posedge clk) - if(Baud8Tick) - case(state) - 4'b0000: if(RxD_bit_inv) state <= 4'b1000; // start bit found? - 4'b1000: if(next_bit) state <= 4'b1001; // bit 0 - 4'b1001: if(next_bit) state <= 4'b1010; // bit 1 - 4'b1010: if(next_bit) state <= 4'b1011; // bit 2 - 4'b1011: if(next_bit) state <= 4'b1100; // bit 3 - 4'b1100: if(next_bit) state <= 4'b1101; // bit 4 - 4'b1101: if(next_bit) state <= 4'b1110; // bit 5 - 4'b1110: if(next_bit) state <= 4'b1111; // bit 6 - 4'b1111: if(next_bit) state <= 4'b0001; // bit 7 - 4'b0001: if(next_bit) state <= 4'b0000; // stop bit - default: state <= 4'b0000; - endcase - - reg [7:0] RxD_data; - always @(posedge clk) - if(Baud8Tick && next_bit && state[3]) RxD_data <= {~RxD_bit_inv, RxD_data[7:1]}; - - reg RxD_data_ready; - always @(posedge clk) - begin - RxD_data_ready <= (Baud8Tick && next_bit && state==4'b0001 && ~RxD_bit_inv); // ready only if the stop bit is received - end - - reg [4:0] gap_count; - always @(posedge clk) if (state!=0) gap_count<=5'h00; else if(Baud8Tick & ~gap_count[4]) gap_count <= gap_count + 5'h01; - assign RxD_idle = gap_count[4]; - reg RxD_endofpacket; always @(posedge clk) RxD_endofpacket <= Baud8Tick & (gap_count==5'h0F); -endmodule - -module async_transmit(clk, TxD_start, TxD_data, TxD, TxD_busy, state); - input clk, TxD_start; - input [7:0] TxD_data; - output TxD, TxD_busy; - output [4:0] state; - parameter ClkFrequency = 25000000; // 25MHz - //parameter ClkFrequency = 50000000; // 50MHz - parameter Baud = 115200; - parameter RegisterInputData = 1; // in RegisterInputData mode, the input doesn't have to stay valid while the character is been transmitted - - // Baud generator - parameter BaudGeneratorAccWidth = 16; - reg [BaudGeneratorAccWidth:0] BaudGeneratorAcc; - `ifdef DEBUG - wire [BaudGeneratorAccWidth:0] BaudGeneratorInc = 17'h10000; - `else - wire [BaudGeneratorAccWidth:0] BaudGeneratorInc = ((Baud<<(BaudGeneratorAccWidth-4))+(ClkFrequency>>5))/(ClkFrequency>>4); - `endif - - wire BaudTick = BaudGeneratorAcc[BaudGeneratorAccWidth]; - wire TxD_busy; - always @(posedge clk) if(TxD_busy) BaudGeneratorAcc <= BaudGeneratorAcc[BaudGeneratorAccWidth-1:0] + BaudGeneratorInc; - - // Transmitter state machine - reg [4:0] state; - wire TxD_ready = (state==0); - assign TxD_busy = ~TxD_ready; - - reg [7:0] TxD_dataReg; - always @(posedge clk) if(TxD_ready & TxD_start) TxD_dataReg <= TxD_data; - wire [7:0] TxD_dataD = RegisterInputData ? TxD_dataReg : TxD_data; - - always @(posedge clk) begin - if (TxD_start == 0) state <= 5'b00000; - - case(state) - 5'b00000: if(TxD_start) state <= 5'b00001; - 5'b00001: if(BaudTick) state <= 5'b00100; - 5'b00100: if(BaudTick) state <= 5'b01000; // start - 5'b01000: if(BaudTick) state <= 5'b01001; // bit 0 - 5'b01001: if(BaudTick) state <= 5'b01010; // bit 1 - 5'b01010: if(BaudTick) state <= 5'b01011; // bit 2 - 5'b01011: if(BaudTick) state <= 5'b01100; // bit 3 - 5'b01100: if(BaudTick) state <= 5'b01101; // bit 4 - 5'b01101: if(BaudTick) state <= 5'b01110; // bit 5 - 5'b01110: if(BaudTick) state <= 5'b01111; // bit 6 - 5'b01111: if(BaudTick) state <= 5'b00010; // bit 7 - 5'b00010: if(BaudTick) state <= 5'b00011; // stop1 - //4'b0011: if(BaudTick) state <= 4'b0000; // stop2 - 5'b00011: if(BaudTick) state <= 5'b10000; // stop2 - //default: if(BaudTick) state <= 4'b0000; - endcase - end - - // Output mux - reg muxbit; - always @( * ) - case(state[2:0]) - 3'd0: muxbit <= TxD_dataD[0]; - 3'd1: muxbit <= TxD_dataD[1]; - 3'd2: muxbit <= TxD_dataD[2]; - 3'd3: muxbit <= TxD_dataD[3]; - 3'd4: muxbit <= TxD_dataD[4]; - 3'd5: muxbit <= TxD_dataD[5]; - 3'd6: muxbit <= TxD_dataD[6]; - 3'd7: muxbit <= TxD_dataD[7]; - endcase - - // Put together the start, data and stop bits - reg TxD; - always @(posedge clk) TxD <= (state<4) | (state[3] & muxbit) | state[4]; // register the output to make it glitch free - -endmodule diff --git a/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/data_storage.v b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/data_storage.v new file mode 100644 index 0000000..b98fb25 --- /dev/null +++ b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/data_storage.v @@ -0,0 +1,33 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// +// (c) 2014 Timothy Pearson, Raptor Engineering +// Released into the Public Domain +// +////////////////////////////////////////////////////////////////////////////////// + +module data_storage( + input clka, + input [7:0] dina, + input [(RAM_ADDR_BITS-1):0] addra, + input wea, + output reg [7:0] douta); + + parameter RAM_ADDR_BITS = 14; + parameter RAM_WIDTH = 8; + + // Xilinx specific directive + (* RAM_STYLE="BLOCK" *) + + reg [RAM_WIDTH-1:0] data_storage_ram [(2**RAM_ADDR_BITS)-1:0]; + + always @(posedge clka) begin + if (wea) begin + data_storage_ram[addra] <= dina; + douta <= dina; + end else begin + douta <= data_storage_ram[addra]; + end + end + +endmodule diff --git a/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/lcd_data_storage.v b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/lcd_data_storage.v new file mode 100644 index 0000000..c1f3559 --- /dev/null +++ b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/lcd_data_storage.v @@ -0,0 +1,44 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// +// (c) 2014 Timothy Pearson, Raptor Engineering +// Released into the Public Domain +// +////////////////////////////////////////////////////////////////////////////////// + +module lcd_data_storage( + input clka, + input clkb, + input [7:0] dina, + input [7:0] dinb, + input [4:0] addra, + input [4:0] addrb, + input wea, + input web, + output reg [7:0] douta, + output reg [7:0] doutb); + + parameter RAM_WIDTH = 8; + + // Xilinx specific directive + (* RAM_STYLE="BLOCK" *) + + reg [RAM_WIDTH-1:0] data_storage_ram [(2**5)-1:0]; + + always @(posedge clka) begin + douta <= data_storage_ram[addra]; + if (wea) begin + data_storage_ram[addra] <= dina; + douta <= dina; + end + end + + always @(posedge clkb) begin + doutb <= data_storage_ram[addrb]; + if (web) begin + data_storage_ram[addrb] <= dinb; + doutb <= dinb; + end + end + +endmodule diff --git a/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/main.ucf b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/main.ucf new file mode 100644 index 0000000..d6ccdcc --- /dev/null +++ b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/main.ucf @@ -0,0 +1,128 @@ +# (c) 2013 Timothy Pearson, Raptor Engineering +# Released into the Public Domain +NET "clk" LOC = "V10" |IOSTANDARD = "LVCMOS33"; +TIMESPEC TS_clk = PERIOD "clk" 100000 KHz HIGH 50%; + +#NET "serial_input" LOC = "T12" | IOSTANDARD = "LVCMOS33"; +#NET "serial_output" LOC = "M10" | SLEW = FAST | IOSTANDARD = "LVCMOS33"; +NET "gpmc_advn" LOC = "C5" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_oen" LOC = "A3" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_wen" LOC = "A5" |IOSTANDARD = "LVCMOS33"; + +NET "gpmc_data<0>" LOC = "A6" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "gpmc_data<1>" LOC = "C8" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "gpmc_data<2>" LOC = "C9" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "gpmc_data<3>" LOC = "A10" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "gpmc_data<4>" LOC = "C10" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "gpmc_data<5>" LOC = "D9" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "gpmc_data<6>" LOC = "D8" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "gpmc_data<7>" LOC = "B6" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; + +NET "gpmc_address<0>" LOC = "A11" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_address<1>" LOC = "F9" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_address<2>" LOC = "A9" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_address<3>" LOC = "A8" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_address<4>" LOC = "A7" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_address<5>" LOC = "C6" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_address<6>" LOC = "A4" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_address<7>" LOC = "A2" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_address<8>" LOC = "B11" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_address<9>" LOC = "G9" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_address<10>" LOC = "B9" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_address<11>" LOC = "B8" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_address<12>" LOC = "C7" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_address<13>" LOC = "D6" |IOSTANDARD = "LVCMOS33"; +NET "gpmc_address<14>" LOC = "B4" |IOSTANDARD = "LVCMOS33"; + +NET "usermem_wen" LOC = "V16" |IOSTANDARD = "LVCMOS33"; +NET "usermem_wait" LOC = "T18" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "userproc_start" LOC = "K16" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "userproc_done" LOC = "L13" |IOSTANDARD = "LVCMOS33"; + +NET "usermem_data<0>" LOC = "V14" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "usermem_data<1>" LOC = "T11" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "usermem_data<2>" LOC = "R11" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "usermem_data<3>" LOC = "T14" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "usermem_data<4>" LOC = "U16" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "usermem_data<5>" LOC = "T17" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "usermem_data<6>" LOC = "K15" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; +NET "usermem_data<7>" LOC = "L12" |SLEW = FAST |IOSTANDARD = "LVCMOS33"; + +NET "usermem_address<0>" LOC = "K12" |IOSTANDARD = "LVCMOS33"; +NET "usermem_address<1>" LOC = "L14" |IOSTANDARD = "LVCMOS33"; +NET "usermem_address<2>" LOC = "M14" |IOSTANDARD = "LVCMOS33"; +NET "usermem_address<3>" LOC = "L15" |IOSTANDARD = "LVCMOS33"; +NET "usermem_address<4>" LOC = "N15" |IOSTANDARD = "LVCMOS33"; +NET "usermem_address<5>" LOC = "P15" |IOSTANDARD = "LVCMOS33"; +NET "usermem_address<6>" LOC = "U17" |IOSTANDARD = "LVCMOS33"; +NET "usermem_address<7>" LOC = "U13" |IOSTANDARD = "LVCMOS33"; +NET "usermem_address<8>" LOC = "V13" |IOSTANDARD = "LVCMOS33"; +NET "usermem_address<9>" LOC = "U18" |IOSTANDARD = "LVCMOS33"; +NET "usermem_address<10>" LOC = "P16" |IOSTANDARD = "LVCMOS33"; +NET "usermem_address<11>" LOC = "N16" |IOSTANDARD = "LVCMOS33"; +NET "usermem_address<12>" LOC = "L16" |IOSTANDARD = "LVCMOS33"; +NET "usermem_address<13>" LOC = "N14" |IOSTANDARD = "LVCMOS33"; +NET "usermem_address<14>" LOC = "M13" |IOSTANDARD = "LVCMOS33"; + +NET "four_bit_leds<0>" LOC = "G13" |IOSTANDARD = "LVCMOS33"; +NET "four_bit_leds<1>" LOC = "H16" |IOSTANDARD = "LVCMOS33"; +NET "four_bit_leds<2>" LOC = "G14" |IOSTANDARD = "LVCMOS33"; +NET "four_bit_leds<3>" LOC = "F16" |IOSTANDARD = "LVCMOS33"; + +NET "eight_bit_leds<0>" LOC = "E18" |IOSTANDARD = "LVCMOS33"; +NET "eight_bit_leds<1>" LOC = "C18" |IOSTANDARD = "LVCMOS33"; +NET "eight_bit_leds<2>" LOC = "A15" |IOSTANDARD = "LVCMOS33"; +NET "eight_bit_leds<3>" LOC = "A14" |IOSTANDARD = "LVCMOS33"; +NET "eight_bit_leds<4>" LOC = "K14" |IOSTANDARD = "LVCMOS33"; +NET "eight_bit_leds<5>" LOC = "H14" |IOSTANDARD = "LVCMOS33"; +NET "eight_bit_leds<6>" LOC = "G18" |IOSTANDARD = "LVCMOS33"; +NET "eight_bit_leds<7>" LOC = "F18" |IOSTANDARD = "LVCMOS33"; + +NET "sixteen_bit_io<0>" LOC = "R10" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<1>" LOC = "T9" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<2>" LOC = "U7" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<3>" LOC = "R7" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<4>" LOC = "N5" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<5>" LOC = "R5" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<6>" LOC = "R3" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<7>" LOC = "T3" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<8>" LOC = "T5" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<9>" LOC = "P6" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<10>" LOC = "T7" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<11>" LOC = "V7" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<12>" LOC = "V9" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<13>" LOC = "T10" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<14>" LOC = "A12" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io<15>" LOC = "B12" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io_wen" LOC = "C11" |IOSTANDARD = "LVCMOS33"; +NET "sixteen_bit_io_mode" LOC = "D11" |IOSTANDARD = "LVCMOS33"; + +NET "four_bit_switches<0>" LOC = "H12" |SLEW = SLOW |IOSTANDARD = "LVCMOS33"; +NET "four_bit_switches<1>" LOC = "H15" |SLEW = SLOW |IOSTANDARD = "LVCMOS33"; +NET "four_bit_switches<2>" LOC = "F14" |SLEW = SLOW |IOSTANDARD = "LVCMOS33"; +NET "four_bit_switches<3>" LOC = "F15" |SLEW = SLOW |IOSTANDARD = "LVCMOS33"; + +NET "eight_bit_switches<0>" LOC = "E16" |SLEW = SLOW |IOSTANDARD = "LVCMOS33"; +NET "eight_bit_switches<1>" LOC = "C17" |SLEW = SLOW |IOSTANDARD = "LVCMOS33"; +NET "eight_bit_switches<2>" LOC = "C15" |SLEW = SLOW |IOSTANDARD = "LVCMOS33"; +NET "eight_bit_switches<3>" LOC = "B14" |SLEW = SLOW |IOSTANDARD = "LVCMOS33"; +NET "eight_bit_switches<4>" LOC = "J13" |SLEW = SLOW |IOSTANDARD = "LVCMOS33"; +NET "eight_bit_switches<5>" LOC = "H13" |SLEW = SLOW |IOSTANDARD = "LVCMOS33"; +NET "eight_bit_switches<6>" LOC = "G16" |SLEW = SLOW |IOSTANDARD = "LVCMOS33"; +NET "eight_bit_switches<7>" LOC = "F17" |SLEW = SLOW |IOSTANDARD = "LVCMOS33"; + +NET "sseg_mux<0>" LOC = "U11" |IOSTANDARD = "LVCMOS33"; +NET "sseg_mux<1>" LOC = "R8" |IOSTANDARD = "LVCMOS33"; +NET "sseg_mux<2>" LOC = "U8" |IOSTANDARD = "LVCMOS33"; +NET "sseg_mux<3>" LOC = "T6" |IOSTANDARD = "LVCMOS33"; + +NET "sseg_data<0>" LOC = "U5" |IOSTANDARD = "LVCMOS33"; +NET "sseg_data<1>" LOC = "T4" |IOSTANDARD = "LVCMOS33"; +NET "sseg_data<2>" LOC = "V4" |IOSTANDARD = "LVCMOS33"; +NET "sseg_data<3>" LOC = "V5" |IOSTANDARD = "LVCMOS33"; +NET "sseg_data<4>" LOC = "V6" |IOSTANDARD = "LVCMOS33"; +NET "sseg_data<5>" LOC = "V8" |IOSTANDARD = "LVCMOS33"; +NET "sseg_data<6>" LOC = "T8" |IOSTANDARD = "LVCMOS33"; +NET "sseg_data<7>" LOC = "V11" |IOSTANDARD = "LVCMOS33"; +#Created by Constraints Editor (xc6slx9-csg324-3) - 2014/01/09 +NET "clk" TNM_NET = clk; diff --git a/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/main.v b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/main.v new file mode 100644 index 0000000..370c3a2 --- /dev/null +++ b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/main.v @@ -0,0 +1,393 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// +// uLab to ARM GPMC interface +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation; either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License along +// with this program; if not, write to the Free Software Foundation, Inc., +// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +// +// (c) 2014 Timothy Pearson +// Raptor Engineering +// http://www.raptorengineeringinc.com +// +////////////////////////////////////////////////////////////////////////////////// + +module main( + input clk, + + input gpmc_advn, + input gpmc_oen, + input gpmc_wen, + inout [7:0] gpmc_data, + input [RAM_ADDR_BITS:0] gpmc_address, + + input usermem_wen, + output reg usermem_wait, + inout [7:0] usermem_data, + inout [RAM_ADDR_BITS:0] usermem_address, + + output reg userproc_start, + input userproc_done, + + input [3:0] four_bit_leds, + input [7:0] eight_bit_leds, + + output reg [3:0] four_bit_switches, + output reg [7:0] eight_bit_switches, + + inout [15:0] sixteen_bit_io, + input sixteen_bit_io_wen, + output reg sixteen_bit_io_mode, + + input [3:0] sseg_mux, + input [7:0] sseg_data); + + parameter RAM_ADDR_BITS = 14; + + reg [15:0] sixteen_bit_io_in; + reg [15:0] sixteen_bit_io_out; + reg [15:0] sixteen_bit_io_reg; + reg sixteen_bit_io_wen_reg; + + assign sixteen_bit_io = (sixteen_bit_io_wen) ? sixteen_bit_io_out : 16'bz; + + always @(posedge clk) begin + sixteen_bit_io_reg = sixteen_bit_io; + sixteen_bit_io_wen_reg = sixteen_bit_io_wen; + if (sixteen_bit_io_wen_reg == 1'b0) begin + sixteen_bit_io_mode = 1'b1; + sixteen_bit_io_in = sixteen_bit_io_reg; + end else begin + sixteen_bit_io_mode = 1'b0; + end + end + + reg [7:0] gpmc_data_out; + reg gpmc_data_driven; + + assign gpmc_data = (gpmc_data_driven) ? gpmc_data_out : 8'bz; + + reg [7:0] usermem_data_out; + + assign usermem_data = (usermem_wen) ? usermem_data_out : 8'bz; + + wire data_storage_clka; + reg [7:0] data_storage_dina; + reg [(RAM_ADDR_BITS-1):0] data_storage_addra; + reg data_storage_write_enable; + wire [7:0] data_storage_data_out; + + assign data_storage_clka = clk; + + data_storage #(RAM_ADDR_BITS) data_storage(.clka(data_storage_clka), .dina(data_storage_dina), .addra(data_storage_addra), + .wea(data_storage_write_enable), .douta(data_storage_data_out)); + + wire lcd_data_storage_clka; + wire lcd_data_storage_clkb; + reg [7:0] lcd_data_storage_dina; + reg [7:0] lcd_data_storage_dinb; + reg [4:0] lcd_data_storage_addra; + reg [4:0] lcd_data_storage_addrb; + reg lcd_data_storage_wea; + reg lcd_data_storage_web; + wire [7:0] lcd_data_storage_douta; + wire [7:0] lcd_data_storage_doutb; + + assign lcd_data_storage_clka = clk; + assign lcd_data_storage_clkb = clk; + + lcd_data_storage lcd_data_storage(.clka(lcd_data_storage_clka), .clkb(lcd_data_storage_clkb), + .dina(lcd_data_storage_dina), .dinb(lcd_data_storage_dinb), + .addra(lcd_data_storage_addra), .addrb(lcd_data_storage_addrb), + .wea(lcd_data_storage_wea), .web(lcd_data_storage_web), + .douta(lcd_data_storage_douta), .doutb(lcd_data_storage_doutb)); + + //----------------------------------------------------------------------------------- + // + // Create a 12.5MHz clock for the seven-segement LED emulator + // + //----------------------------------------------------------------------------------- + + reg clk_div_by_two; + reg clk_div_by_two_oneeighty; + reg clk_div_by_four; + reg clk_div_by_eight; + reg clk_div_by_sixteen; + + always @(posedge clk) begin + clk_div_by_two = !clk_div_by_two; + end + + always @(negedge clk_div_by_two) begin + clk_div_by_two_oneeighty = !clk_div_by_two_oneeighty; + end + + always @(posedge clk_div_by_two_oneeighty) begin + clk_div_by_four = !clk_div_by_four; + end + + always @(posedge clk_div_by_four) begin + clk_div_by_eight = !clk_div_by_eight; + end + + always @(posedge clk_div_by_eight) begin + clk_div_by_sixteen = !clk_div_by_sixteen; + end + + + //----------------------------------------------------------------------------------- + // + // Keep track of what is on the LED display + // + //----------------------------------------------------------------------------------- + + reg [7:0] led_display_bytes [3:0]; + reg [17:0] digit_blanker_1 = 0; + reg [17:0] digit_blanker_2 = 0; + reg [17:0] digit_blanker_3 = 0; + reg [17:0] digit_blanker_4 = 0; + + reg [7:0] sseg_data_latch; + reg [3:0] sseg_mux_latch; + + always @(negedge clk_div_by_sixteen) begin + sseg_data_latch = sseg_data; + sseg_mux_latch = sseg_mux; + + if (sseg_mux_latch[0] == 0) begin + led_display_bytes[0] = sseg_data_latch; + digit_blanker_1 = 0; + digit_blanker_2 = digit_blanker_2 + 1; + digit_blanker_3 = digit_blanker_3 + 1; + digit_blanker_4 = digit_blanker_4 + 1; + end + + if (sseg_mux_latch[1] == 0) begin + led_display_bytes[1] = sseg_data_latch; + digit_blanker_1 = digit_blanker_1 + 1; + digit_blanker_2 = 0; + digit_blanker_3 = digit_blanker_3 + 1; + digit_blanker_4 = digit_blanker_4 + 1; + end + + if (sseg_mux_latch[2] == 0) begin + led_display_bytes[2] = sseg_data_latch; + digit_blanker_1 = digit_blanker_1 + 1; + digit_blanker_2 = digit_blanker_2 + 1; + digit_blanker_3 = 0; + digit_blanker_4 = digit_blanker_4 + 1; + end + + if (sseg_mux_latch[3] == 0) begin + led_display_bytes[3] = sseg_data_latch; + digit_blanker_1 = digit_blanker_1 + 1; + digit_blanker_2 = digit_blanker_2 + 1; + digit_blanker_3 = digit_blanker_3 + 1; + digit_blanker_4 = 0; + end + + if (digit_blanker_1 > 128000) begin + led_display_bytes[0] = 255; + end + + if (digit_blanker_2 > 128000) begin + led_display_bytes[1] = 255; + end + + if (digit_blanker_3 > 128000) begin + led_display_bytes[2] = 255; + end + + if (digit_blanker_4 > 128000) begin + led_display_bytes[3] = 255; + end + end + + + //----------------------------------------------------------------------------------- + // + // Memory and register access + // + //----------------------------------------------------------------------------------- + + reg gpmc_advn_reg; + reg gpmc_oen_reg; + reg gpmc_wen_reg; + reg [7:0] gpmc_data_reg; + reg [RAM_ADDR_BITS:0] gpmc_address_reg; + + reg usermem_wen_reg; + reg [7:0] usermem_data_reg; + reg [RAM_ADDR_BITS:0] usermem_address_reg; + + always @(posedge clk) begin + usermem_wen_reg = usermem_wen; + usermem_data_reg = usermem_data; + usermem_address_reg = usermem_address; + + gpmc_advn_reg = gpmc_advn; + gpmc_oen_reg = gpmc_oen; + gpmc_wen_reg = gpmc_wen; + gpmc_data_reg = gpmc_data; + if (gpmc_advn_reg == 1'b0) begin + gpmc_address_reg = gpmc_address; + data_storage_write_enable = 1'b0; + lcd_data_storage_wea = 1'b0; + end + + if (gpmc_address_reg[RAM_ADDR_BITS] == 1'b1) begin + // System memory access + usermem_wait = 1'b1; + if (gpmc_wen_reg == 1'b0) begin + data_storage_addra = gpmc_address_reg[(RAM_ADDR_BITS-1):0]; + data_storage_dina = gpmc_data_reg; + data_storage_write_enable = 1'b1; + end else begin + data_storage_addra = gpmc_address_reg[(RAM_ADDR_BITS-1):0]; + data_storage_write_enable = 1'b0; + gpmc_data_out = data_storage_data_out; + end + end else begin + // User memory access + usermem_wait = 1'b0; + if (usermem_address_reg[RAM_ADDR_BITS] == 1'b1) begin + // Interdevice communication region + // MEMORY MAP + // 0x20 - 0x3f: LCD data area + if (usermem_wen_reg == 1'b0) begin + if (usermem_address_reg[(RAM_ADDR_BITS-1):5] == 1) begin // Address range 0x20 - 0x3f + lcd_data_storage_addrb = usermem_address_reg[4:0]; + lcd_data_storage_dinb = usermem_data_reg; + lcd_data_storage_web = 1'b1; + end + end else begin + if (usermem_address_reg[(RAM_ADDR_BITS-1):5] == 1) begin // Address range 0x20 - 0x3f + lcd_data_storage_addrb = usermem_address_reg[4:0]; + lcd_data_storage_web = 1'b0; + usermem_data_out = lcd_data_storage_doutb; + end else begin + // Default + usermem_data_out = 8'b00000000; + end + end + end else begin + // Client scratchpad memory area + if (usermem_wen_reg == 1'b0) begin + data_storage_addra = usermem_address_reg[(RAM_ADDR_BITS-1):0]; + data_storage_dina = usermem_data_reg; + data_storage_write_enable = 1'b1; + end else begin + data_storage_addra = usermem_address_reg[(RAM_ADDR_BITS-1):0]; + data_storage_write_enable = 1'b0; + usermem_data_out = data_storage_data_out; + end + end + + // Configuration register access + // MEMORY MAP + // 0x00: Model number (read only) + // 0x01: Version (read only) + // 0x02: 4-bit I/O (lower 4 bits only) + // 0x03: 8-bit I/O + // 0x04: 16-bit I/O (upper 8 bits) + // 0x05: 16-bit I/O (lower 8 bits) + // 0x06: 7-segment LED digit 0 (read only) + // 0x07: 7-segment LED digit 1 (read only) + // 0x08: 7-segment LED digit 2 (read only) + // 0x09: 7-segment LED digit 3 (read only) + // 0x0a: User process register + // Bit 0: User processing start + // Bit 1: User processing done (read only) + // 0x20 - 0x3f: LCD data area + if (gpmc_wen_reg == 1'b0) begin + if (gpmc_address_reg[(RAM_ADDR_BITS-1):5] == 1) begin // Address range 0x20 - 0x3f + lcd_data_storage_addra = gpmc_address_reg[4:0]; + lcd_data_storage_dina = gpmc_data_reg; + lcd_data_storage_wea = 1'b1; + end else begin + case (gpmc_address_reg[(RAM_ADDR_BITS-1):0]) + 2: begin + four_bit_switches = gpmc_data_reg[3:0]; + end + 3: begin + eight_bit_switches = gpmc_data_reg; + end + 4: begin + sixteen_bit_io_out[15:8] = gpmc_data_reg; + end + 5: begin + sixteen_bit_io_out[7:0] = gpmc_data_reg; + end + 10: begin + userproc_start = gpmc_data_reg[0]; + end + default: begin + // Do nothing + end + endcase + end + end else begin + if (gpmc_address_reg[(RAM_ADDR_BITS-1):5] == 1) begin // Address range 0x20 - 0x3f + lcd_data_storage_addra = gpmc_address_reg[4:0]; + lcd_data_storage_wea = 1'b0; + gpmc_data_out = lcd_data_storage_douta; + end else begin + case (gpmc_address_reg[(RAM_ADDR_BITS-1):0]) + 0: begin + gpmc_data_out = 8'b01000010; + end + 1: begin + gpmc_data_out = 8'b00000001; + end + 2: begin + gpmc_data_out[7:4] = 0; + gpmc_data_out[3:0] = four_bit_leds; + end + 3: begin + gpmc_data_out = eight_bit_leds; + end + 4: begin + gpmc_data_out = sixteen_bit_io_in[15:8]; + end + 5: begin + gpmc_data_out = sixteen_bit_io_in[7:0]; + end + 6: begin + gpmc_data_out = led_display_bytes[0]; + end + 7: begin + gpmc_data_out = led_display_bytes[1]; + end + 8: begin + gpmc_data_out = led_display_bytes[2]; + end + 9: begin + gpmc_data_out = led_display_bytes[3]; + end + 10: begin + gpmc_data_out[0] = userproc_start; + gpmc_data_out[1] = userproc_done; + gpmc_data_out[7:2] = 0; + end + default: begin + gpmc_data_out = 0; + end + endcase + end + end + end + + gpmc_data_driven = ((~gpmc_oen) && gpmc_wen); + end +endmodule diff --git a/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/ulab_debug_interface.xise b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/ulab_debug_interface.xise new file mode 100644 index 0000000..849b25c --- /dev/null +++ b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/ulab_debug_interface.xise @@ -0,0 +1,409 @@ + + + +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/fpga/serial/common/remote_access.v b/fpga/serial/common/remote_access.v new file mode 100644 index 0000000..5a37e86 --- /dev/null +++ b/fpga/serial/common/remote_access.v @@ -0,0 +1,1253 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// Company: Raptor Engineering +// Engineer: Timothy Pearson +// +// Design Name: Remote Access Driver +// Module Name: remote_access +// Project Name: Remote Access Driver +// Target Devices: Any +// Description: Serial remote access driver and LCD display driver +// +// Dependencies: +// +// (c) 2007-2013 Timothy Pearson, Raptor Engineering +// Released into the Public Domain +// +////////////////////////////////////////////////////////////////////////////////// +module remote_access( + input main_fifty_clock, // 50MHz clock in + input [3:0] remote_access_4_bit_output, // 4 bit output from the user program to remote access client + output [3:0] remote_access_4_bit_input, // 4 bit input from the remote access client to user program + input [7:0] remote_access_8_bit_output, // 8 bit output from the user program to remote access client + output [7:0] remote_access_8_bit_input, // 8 bit input from the remote access client to user program + input [15:0] remote_access_16_bit_output, // 16 bit output from the user program to the remote access client + output [15:0] remote_access_16_bit_input, // 16 bit input from the remote access client to the user program + input serial_port_receiver, + output serial_port_transmitter, + input remote_access_input_enable, + input [7:0] local_input, + input seize_serial_tx, + input [7:0] serial_tx_data, + input serial_tx_strobe, + output [7:0] serial_rx_data, + output serial_rx_strobe, + input [5:0] lcd_data_in_address, + input [7:0] lcd_data_in_data, + input lcd_data_in_enable, + input sram_wren_in, + input sram_clock_in, + input [7:0] sram_data_in, + input [(RAM_ADDR_BITS-1):0] sram_address_in, + output [7:0] sram_data_out, + output sram_available, + input sram_processing_done, + input [7:0] led_segment_bus, + input [3:0] led_digit_select, + + // For use on Digilent Spartan 3E or compatible board only + output [3:0] remote_access_lcd_data_out, + output remote_access_lcd_rs_out, + output remote_access_lcd_rw_out, + output remote_access_lcd_enable_out); + + parameter RAM_ADDR_BITS = 14; + + reg [7:0] remote_access_4_bit_input_reg; + reg [7:0] remote_access_8_bit_input_reg; + reg [15:0] remote_access_16_bit_input_reg; + reg [3:0] remote_access_lcd_data_out_reg; + reg remote_access_lcd_rs_out_reg; + reg remote_access_lcd_rw_out_reg; + reg remote_access_lcd_enable_out_reg; + reg [7:0] serial_rx_data_reg; + reg serial_rx_strobe_reg; + reg sram_available_reg; + reg startup_needed = 1; + + assign remote_access_4_bit_input = remote_access_4_bit_input_reg[3:0]; + assign remote_access_8_bit_input = remote_access_8_bit_input_reg; + assign remote_access_16_bit_input = remote_access_16_bit_input_reg; + assign remote_access_lcd_data_out = remote_access_lcd_data_out_reg; + assign remote_access_lcd_rs_out = remote_access_lcd_rs_out_reg; + assign remote_access_lcd_rw_out = remote_access_lcd_rw_out_reg; + assign remote_access_lcd_enable_out = remote_access_lcd_enable_out_reg; + assign serial_rx_data = serial_rx_data_reg; + assign serial_rx_strobe = serial_rx_strobe_reg; + assign sram_available = sram_available_reg; + + //----------------------------------------------------------------------------------- + // + // Create a 4.16MHz clock for the LCD display driver and a 25MHz clock + // for the serial receiver. + // + //----------------------------------------------------------------------------------- + + reg four_mhz_clk; + reg clk_div_by_two; + reg clk_div_by_two_oneeighty; + reg clk_div_by_four; + reg clk_div_by_eight; + reg [3:0] fifty_clock_divider = 0; + + always @(posedge main_fifty_clock) begin + fifty_clock_divider = fifty_clock_divider + 1; + if (fifty_clock_divider > 12) begin + four_mhz_clk = !four_mhz_clk; + fifty_clock_divider = 0; + end + end + + always @(posedge main_fifty_clock) begin + clk_div_by_two = !clk_div_by_two; + end + + always @(negedge main_fifty_clock) begin + clk_div_by_two_oneeighty = !clk_div_by_two_oneeighty; + end + + always @(posedge clk_div_by_two_oneeighty) begin + clk_div_by_four = !clk_div_by_four; + end + + always @(posedge clk_div_by_four) begin + clk_div_by_eight = !clk_div_by_eight; + end + + //----------------------------------------------------------------------------------- + // + // Keep track of what is on the LED display + // + //----------------------------------------------------------------------------------- + + reg [7:0] led_display_bytes [3:0]; + reg [17:0] digit_blanker_1 = 0; + reg [17:0] digit_blanker_2 = 0; + reg [17:0] digit_blanker_3 = 0; + reg [17:0] digit_blanker_4 = 0; + + reg [7:0] led_segment_bus_latch; + reg [3:0] led_digit_select_latch; + + always @(negedge clk_div_by_eight) begin + led_segment_bus_latch = led_segment_bus; + led_digit_select_latch = led_digit_select; + + if (led_digit_select_latch[0] == 0) begin + led_display_bytes[0] = led_segment_bus_latch; + digit_blanker_1 = 0; + digit_blanker_2 = digit_blanker_2 + 1; + digit_blanker_3 = digit_blanker_3 + 1; + digit_blanker_4 = digit_blanker_4 + 1; + end + + if (led_digit_select_latch[1] == 0) begin + led_display_bytes[1] = led_segment_bus_latch; + digit_blanker_1 = digit_blanker_1 + 1; + digit_blanker_2 = 0; + digit_blanker_3 = digit_blanker_3 + 1; + digit_blanker_4 = digit_blanker_4 + 1; + end + + if (led_digit_select_latch[2] == 0) begin + led_display_bytes[2] = led_segment_bus_latch; + digit_blanker_1 = digit_blanker_1 + 1; + digit_blanker_2 = digit_blanker_2 + 1; + digit_blanker_3 = 0; + digit_blanker_4 = digit_blanker_4 + 1; + end + + if (led_digit_select_latch[3] == 0) begin + led_display_bytes[3] = led_segment_bus_latch; + digit_blanker_1 = digit_blanker_1 + 1; + digit_blanker_2 = digit_blanker_2 + 1; + digit_blanker_3 = digit_blanker_3 + 1; + digit_blanker_4 = 0; + end + + if (digit_blanker_1 > 128000) begin + led_display_bytes[0] = 255; + end + + if (digit_blanker_2 > 128000) begin + led_display_bytes[1] = 255; + end + + if (digit_blanker_3 > 128000) begin + led_display_bytes[2] = 255; + end + + if (digit_blanker_4 > 128000) begin + led_display_bytes[3] = 255; + end + end + + //----------------------------------------------------------------------------------- + // + // Instantiate the data storage RAM for signal processing + // + //----------------------------------------------------------------------------------- + + reg data_storage_remote_enable = 0; + wire data_storage_clka; + wire [7:0] data_storage_dina; + wire [(RAM_ADDR_BITS-1):0] data_storage_addra; + wire data_storage_write_enable; + wire [7:0] data_storage_data_out; + + reg [7:0] data_storage_dina_reg; + reg [(RAM_ADDR_BITS-1):0] data_storage_addra_reg; + reg data_storage_write_enable_reg; + + data_storage #(RAM_ADDR_BITS) data_storage(.clka(data_storage_clka), .dina(data_storage_dina), .addra(data_storage_addra), + .wea(data_storage_write_enable), .douta(data_storage_data_out)); + + assign data_storage_clka = (data_storage_remote_enable) ? main_fifty_clock : sram_clock_in; + assign data_storage_dina = (data_storage_remote_enable) ? data_storage_dina_reg : sram_data_in; + assign data_storage_addra = (data_storage_remote_enable) ? data_storage_addra_reg : sram_address_in; + assign data_storage_write_enable = (data_storage_remote_enable) ? data_storage_write_enable_reg : sram_wren_in; + + assign sram_data_out = data_storage_data_out; + + // ----------------------------------------------------------------------------------------------- + // + // Here is the serial receiver and transmitter + // + // ----------------------------------------------------------------------------------------------- + + reg [7:0] transmit_all_data_state = 0; + + wire RxD_data_ready; + wire [7:0] RxD_data; + wire RxD_endofpacket; + wire RxD_idle; + + reg TxD_start; + reg [7:0] TxD_data; + wire TxD_busy; + wire [4:0] state; + + reg [7:0] transmitter_4_bit_state = 0; + reg [7:0] transmitter_8_bit_state = 0; + reg [15:0] transmitter_16_bit_state = 0; + reg [7:0] transmitter_main_state = 0; + reg [7:0] transmitter_input_state = 0; + + async_transmit asyncTX(.clk(clk_div_by_two), .TxD_start(TxD_start), .TxD_data(TxD_data), .TxD(serial_port_transmitter), .TxD_busy(TxD_busy), .state(state)); + async_receiver asyncRX(.clk(clk_div_by_two), .RxD(serial_port_receiver), .RxD_data_ready(RxD_data_ready), .RxD_data(RxD_data), .RxD_endofpacket(RxD_endofpacket), .RxD_idle(RxD_idle)); + + reg tx_toggle = 0; + + reg transmit_4_bit_status = 0; + reg transmit_4_bit_status_done = 0; + + reg transmit_8_bit_status = 0; + reg transmit_8_bit_status_done = 0; + + reg transmit_16_bit_status = 0; + reg transmit_16_bit_pass_two = 0; + reg transmit_16_bit_status_done = 0; + + reg transmit_main_status = 0; + reg transmit_main_status_done = 0; + + reg transmit_dsp_ram_size = 0; + reg transmit_dsp_ram_size_done = 0; + + reg transmit_input_status = 0; + reg transmit_input_status_done = 0; + + reg transmit_lcd_status = 0; + reg transmit_lcd_status_done = 0; + reg [7:0] transmit_lcd_status_counter = 0; + + reg enable_remote_access_input = 1; + reg remote_access_input_enable_prev = 0; + + reg [7:0] lcd_display_string [31:0]; + + reg transmit_dsp_status = 0; + reg transmit_dsp_status_done = 0; + reg transmit_dsp_status_holdoff = 0; + reg [RAM_ADDR_BITS:0] transmit_dsp_status_counter = 0; + + reg transmit_led_status = 0; + reg transmit_led_status_done = 0; + reg [7:0] transmit_led_status_counter = 0; + + reg transmit_dsp_rx_complete = 0; + reg transmit_dsp_rx_complete_done = 0; + + // Transmit! + always @(posedge clk_div_by_two) begin + transmitter_4_bit_state = remote_access_4_bit_output; + transmitter_8_bit_state = remote_access_8_bit_output; + transmitter_16_bit_state = remote_access_16_bit_output; + + transmitter_main_state = 0; + transmitter_main_state[0] = enable_remote_access_input; + + transmitter_input_state = local_input; + + if (seize_serial_tx == 1) begin + TxD_start = serial_tx_strobe; + TxD_data = serial_tx_data; + end else begin + if (tx_toggle == 0) begin + if ((transmit_4_bit_status == 1) && (transmit_4_bit_status_done == 0)) begin + TxD_data = transmitter_4_bit_state; + + TxD_start = 1; + tx_toggle = 1; + + transmit_4_bit_status_done = 1; + end + + if ((transmit_8_bit_status == 1) && (transmit_8_bit_status_done == 0)) begin + TxD_data = transmitter_8_bit_state; + + TxD_start = 1; + tx_toggle = 1; + + transmit_8_bit_status_done = 1; + end + + if ((transmit_16_bit_status == 1) && (transmit_16_bit_status_done == 0)) begin + if (transmit_16_bit_pass_two == 0) begin + TxD_data = transmitter_16_bit_state[15:8]; + + TxD_start = 1; + tx_toggle = 1; + + transmit_16_bit_pass_two = 1; + end else begin + TxD_data = transmitter_16_bit_state[7:0]; + + TxD_start = 1; + tx_toggle = 1; + + transmit_16_bit_status_done = 1; + end + end + + if ((transmit_main_status == 1) && (transmit_main_status_done == 0)) begin + TxD_data = transmitter_main_state; + + TxD_start = 1; + tx_toggle = 1; + + transmit_main_status_done = 1; + end + + if ((transmit_dsp_ram_size == 1) && (transmit_dsp_ram_size_done == 0)) begin + TxD_data = RAM_ADDR_BITS; + + TxD_start = 1; + tx_toggle = 1; + + transmit_dsp_ram_size_done = 1; + end + + if ((transmit_input_status == 1) && (transmit_input_status_done == 0)) begin + TxD_data = transmitter_input_state; + + TxD_start = 1; + tx_toggle = 1; + + transmit_input_status_done = 1; + end + + if ((transmit_lcd_status == 1) && (transmit_lcd_status_done == 0)) begin + TxD_data = lcd_display_string[transmit_lcd_status_counter]; + + TxD_start = 1; + tx_toggle = 1; + + transmit_lcd_status_counter = transmit_lcd_status_counter + 1; + if (transmit_lcd_status_counter > 31) begin + transmit_lcd_status_done = 1; + end + end + + if ((transmit_led_status == 1) && (transmit_led_status_done == 0)) begin + TxD_data = led_display_bytes[transmit_led_status_counter]; + + TxD_start = 1; + tx_toggle = 1; + + transmit_led_status_counter = transmit_led_status_counter + 1; + if (transmit_led_status_counter > 3) begin + transmit_led_status_done = 1; + end + end + + if ((transmit_dsp_rx_complete == 1) && (transmit_dsp_rx_complete_done == 0)) begin + TxD_data = 77; + + TxD_start = 1; + tx_toggle = 1; + + transmit_dsp_rx_complete_done = 1; + end + + if ((transmit_dsp_status == 1) && (transmit_dsp_rx_complete == 0) && (transmit_dsp_status_done == 0)) begin + if (transmit_dsp_status_holdoff == 0) begin + transmit_dsp_status_holdoff = 1; + data_storage_write_enable_reg = 0; + data_storage_addra_reg = 0; // Initial data value + end else begin + data_storage_write_enable_reg = 0; + TxD_data = data_storage_data_out; + + TxD_start = 1; + tx_toggle = 1; + + transmit_dsp_status_counter = transmit_dsp_status_counter + 1; + data_storage_addra_reg = transmit_dsp_status_counter[(RAM_ADDR_BITS-1):0]; + if (transmit_dsp_status_counter >= (2**RAM_ADDR_BITS)) begin + transmit_dsp_status_done = 1; + data_storage_write_enable_reg = 1'bz; + data_storage_addra_reg = {(RAM_ADDR_BITS){1'bz}}; + end + end + end + end else begin + if (state == 5'b10000) begin // Wait for transmission of byte to complete + TxD_start = 0; + tx_toggle = 0; + end + end + end + + if (transmit_4_bit_status == 0) begin + transmit_4_bit_status_done = 0; + end + + if (transmit_8_bit_status == 0) begin + transmit_8_bit_status_done = 0; + end + + if (transmit_16_bit_status == 0) begin + transmit_16_bit_pass_two = 0; + transmit_16_bit_status_done = 0; + end + + if (transmit_main_status == 0) begin + transmit_main_status_done = 0; + end + + if (transmit_dsp_ram_size == 0) begin + transmit_dsp_ram_size_done = 0; + end + + if (transmit_input_status == 0) begin + transmit_input_status_done = 0; + end + + if (transmit_lcd_status == 0) begin + transmit_lcd_status_done = 0; + transmit_lcd_status_counter = 0; + end + + if (transmit_led_status == 0) begin + transmit_led_status_done = 0; + transmit_led_status_counter = 0; + end + + if (transmit_dsp_rx_complete == 0) begin + transmit_dsp_rx_complete_done = 0; + end + + if (transmit_dsp_status == 0) begin + transmit_dsp_status_done = 0; + transmit_dsp_status_holdoff = 0; + transmit_dsp_status_counter = 0; + end + end + + reg [7:0] lcd_display_initialization_state = 0; + reg serial_character_received = 0; + reg [7:0] serial_receiver_toggler = 0; + reg [7:0] serial_command_buffer = 0; + reg [2:0] next_byte_is_command = 0; + reg [7:0] next_byte_is_command_prev_command = 0; + reg [7:0] serial_command_timer = 0; + reg update_lcd_display = 0; + reg [7:0] serial_update_counter = 0; + reg [RAM_ADDR_BITS:0] dsp_update_counter = 0; + reg [7:0] received_lcd_display_string [31:0]; + reg data_write_timer = 0; + reg waiting_on_dsp_processing = 0; + + // Receive serial commands + always @(posedge clk_div_by_two) begin + if (startup_needed == 1) begin + startup_needed = 0; + transmit_dsp_status = 1; + end + + if (lcd_data_in_enable == 1) begin + received_lcd_display_string[lcd_data_in_address] = lcd_data_in_data; + update_lcd_display = 1; + serial_command_timer = 255; + end + + if ((remote_access_input_enable == 1) && (remote_access_input_enable_prev == 0)) begin + enable_remote_access_input = !enable_remote_access_input; + end + remote_access_input_enable_prev = remote_access_input_enable; + + if (enable_remote_access_input == 0) begin + // Enable local input + remote_access_8_bit_input_reg = local_input; + end + + if (serial_command_timer > 0) begin + serial_command_timer = serial_command_timer - 1; + end else begin + update_lcd_display = 0; + end + + if (transmit_4_bit_status_done == 1) begin + transmit_4_bit_status = 0; + if (transmit_all_data_state == 1) begin + transmit_8_bit_status = 1; + end + end + + if (transmit_8_bit_status_done == 1) begin + transmit_8_bit_status = 0; + if (transmit_all_data_state == 1) begin + transmit_16_bit_status = 1; + end + end + + if (transmit_16_bit_status_done == 1) begin + transmit_16_bit_status = 0; + if (transmit_all_data_state == 1) begin + transmit_led_status = 1; + end + end + + if (transmit_led_status_done == 1) begin + transmit_led_status = 0; + if (transmit_all_data_state == 1) begin + transmit_all_data_state = 0; + end + end + + if (transmit_dsp_rx_complete_done == 1) begin + transmit_dsp_rx_complete = 0; + end + + if (transmit_main_status_done == 1) begin + transmit_main_status = 0; + if (transmit_all_data_state == 1) begin + transmit_dsp_ram_size = 1; + end + end + + if (transmit_dsp_ram_size_done == 1) begin + transmit_dsp_ram_size = 0; + if (transmit_all_data_state == 1) begin + transmit_4_bit_status = 1; + end + end + + if (transmit_input_status_done == 1) begin + transmit_input_status = 0; + end + + if (transmit_lcd_status_done == 1) begin + transmit_lcd_status = 0; + if (transmit_all_data_state == 1) begin + transmit_main_status = 1; + end + end + + if (transmit_dsp_status_done == 1) begin + transmit_dsp_status = 0; + data_storage_remote_enable = 0; + end + + if (transmit_dsp_status == 1) begin + data_storage_remote_enable = 1; + end + + if (data_write_timer > 1) begin + data_write_timer = data_write_timer - 1; + end else begin + if (data_write_timer == 1) begin + data_storage_write_enable_reg = 0; + data_write_timer = 0; + end + end + + if ((waiting_on_dsp_processing == 1) && (sram_processing_done == 1)) begin + waiting_on_dsp_processing = 0; + transmit_dsp_status = 1; + end + + serial_rx_strobe_reg = 0; // Make sure that this get reset! + + if ((sram_processing_done == 1) && (sram_available_reg == 1)) begin + sram_available_reg = 0; + transmit_dsp_status = 1; + end + + if (RxD_data_ready == 1) begin + if (serial_character_received == 0) begin + serial_rx_data_reg = RxD_data; + serial_rx_strobe_reg = 1; // Signal new data... + if (seize_serial_tx == 0) begin + if (next_byte_is_command_prev_command == 77) begin + // DSP input data + if (dsp_update_counter < (2**RAM_ADDR_BITS)) begin + data_storage_remote_enable = 1; + data_storage_addra_reg = dsp_update_counter[(RAM_ADDR_BITS-1):0]; + data_storage_dina_reg = serial_rx_data_reg; + data_storage_write_enable_reg = 1; + data_write_timer = 3; + dsp_update_counter = dsp_update_counter + 1; + + // TESTING ONLY!!! + //if (dsp_update_counter < 17) begin + // received_lcd_display_string[dsp_update_counter - 1] = serial_command_buffer; + //end + + if (dsp_update_counter >= (2**RAM_ADDR_BITS)) begin + next_byte_is_command = 0; + data_storage_write_enable_reg = 0; + data_storage_remote_enable = 0; + sram_available_reg = 1; + data_storage_write_enable_reg = 1'bz; + data_storage_addra_reg = {(RAM_ADDR_BITS){1'bz}}; + waiting_on_dsp_processing = 1; + transmit_dsp_rx_complete = 1; + next_byte_is_command_prev_command = 0; + + // TESTING ONLY!!! + //transmit_dsp_status = 1; + end + end + end else begin + // Parse the command and see what it is + serial_character_received = 1; + if (serial_rx_data_reg == 13) begin + // Carriage Return! The serial_command_buffer holds the command! Parse it! + if (next_byte_is_command == 0) begin + if (serial_command_buffer == 65) begin + // Display update requested + next_byte_is_command = 1; + serial_update_counter = 0; + next_byte_is_command_prev_command = 65; + end + + if (serial_command_buffer == 66) begin + // 8 bit input update + if (enable_remote_access_input == 1) begin + next_byte_is_command = 1; + serial_update_counter = 0; + next_byte_is_command_prev_command = 66; + end + end + + if (serial_command_buffer == 67) begin + // 16 bit input update + next_byte_is_command = 1; + serial_update_counter = 0; + next_byte_is_command_prev_command = 67; + end + + if (serial_command_buffer == 68) begin + // 8 bit output status + transmit_8_bit_status = 1; + end + + if (serial_command_buffer == 69) begin + // 16 bit output status + transmit_16_bit_status = 1; + end + + if (serial_command_buffer == 70) begin + // System status + transmit_main_status = 1; + end + + if (serial_command_buffer == 71) begin + // Simulate center button press + enable_remote_access_input = !enable_remote_access_input; + end + + if (serial_command_buffer == 72) begin + // Local input status + transmit_input_status = 1; + end + + if (serial_command_buffer == 73) begin + // 4 bit input update + if (enable_remote_access_input == 1) begin + next_byte_is_command = 1; + serial_update_counter = 0; + next_byte_is_command_prev_command = 73; + end + end + + if (serial_command_buffer == 74) begin + // 4 bit output status + transmit_4_bit_status = 1; + end + + if (serial_command_buffer == 75) begin + // Transmit the contents of the LCD... + transmit_lcd_status = 1; + end + + if (serial_command_buffer == 76) begin + // Transmit the contents of the LCD... + transmit_all_data_state = 1; + transmit_lcd_status = 1; + end + + if (serial_command_buffer == 77) begin + // Receive offline DSP data + next_byte_is_command = 1; + dsp_update_counter = 0; + next_byte_is_command_prev_command = 77; + end + + if (serial_command_buffer == 78) begin + // Transmit the contents of RAM... + transmit_dsp_status = 1; + end + + if (serial_command_buffer == 79) begin + // Transmit the DSP RAM size + transmit_dsp_ram_size = 1; + end + end else begin + if (next_byte_is_command == 1) begin + // The previous byte was the command--now load in the data! + if (next_byte_is_command_prev_command == 65) begin + if (serial_update_counter < 32) begin + received_lcd_display_string[serial_update_counter] = serial_command_buffer; + serial_update_counter = serial_update_counter + 1; + end else begin + update_lcd_display = 1; + serial_command_timer = 255; + next_byte_is_command = 0; + end + end + + // 4 bit input update + if (next_byte_is_command_prev_command == 73) begin + remote_access_4_bit_input_reg = serial_command_buffer; + next_byte_is_command = 0; + end + + // 8 bit input update + if (next_byte_is_command_prev_command == 66) begin + remote_access_8_bit_input_reg = serial_command_buffer; + next_byte_is_command = 0; + end + + // 16 bit input update + if (next_byte_is_command_prev_command == 67) begin + if (serial_update_counter == 0) begin + remote_access_16_bit_input_reg[15:8] = serial_command_buffer; + serial_update_counter = 1; + end else begin + remote_access_16_bit_input_reg[7:0] = serial_command_buffer; + next_byte_is_command = 0; + end + end + end + end + end + end + end + + //if (RxD_data != 10) begin // Ignore linefeeds + serial_command_buffer = RxD_data; + //end + + serial_receiver_toggler = serial_receiver_toggler + 1; + end + end + + if (RxD_data_ready == 0) begin + serial_character_received = 0; + end + end + + //----------------------------------------------------------------------------------- + // + // This routine will display the contents of lcd_display_string on the LCD display + // + //----------------------------------------------------------------------------------- + + reg [15:0] lcd_display_wait_counter = 0; + reg [7:0] lcd_display_current_character = 0; + reg lcd_display_line_two = 0; // Are we trying to write to line two? + + always @(posedge four_mhz_clk) begin + case (lcd_display_initialization_state) + // Initialize the display according to the reference manual + 0:begin + // Set up the default display... + lcd_display_string[0] = 73; // I + lcd_display_string[1] = 110; // n + lcd_display_string[2] = 105; // i + lcd_display_string[3] = 116; // t + lcd_display_string[4] = 105; // i + lcd_display_string[5] = 97; // a + lcd_display_string[6] = 108; // l + lcd_display_string[7] = 105; // i + lcd_display_string[8] = 122; // z + lcd_display_string[9] = 97; // a + lcd_display_string[10] = 116; // t + lcd_display_string[11] = 105; // i + lcd_display_string[12] = 111; // o + lcd_display_string[13] = 110; // n + lcd_display_string[14] = 32; // + lcd_display_string[15] = 32; // + lcd_display_string[16] = 79; // O + lcd_display_string[17] = 75; // k + lcd_display_string[18] = 32; // + lcd_display_string[19] = 32; // + lcd_display_string[20] = 32; // + lcd_display_string[21] = 32; // + lcd_display_string[22] = 32; // + lcd_display_string[23] = 32; // + lcd_display_string[24] = 32; // + lcd_display_string[25] = 32; // + lcd_display_string[26] = 32; // + lcd_display_string[27] = 32; // + lcd_display_string[28] = 32; // + lcd_display_string[29] = 32; // + lcd_display_string[30] = 32; // + lcd_display_string[31] = 32; // + + lcd_display_current_character = 0; + + lcd_display_line_two = 0; + remote_access_lcd_data_out_reg = 3; + remote_access_lcd_enable_out_reg = 1; + remote_access_lcd_rs_out_reg = 0; + remote_access_lcd_rw_out_reg = 0; + lcd_display_wait_counter = 17083; // Wait 15mS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 1:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 2:begin + remote_access_lcd_data_out_reg = 3; + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 417; // Wait 100uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 3:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 4:begin + remote_access_lcd_data_out_reg = 3; + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 167; // Wait 40uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 5:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 6:begin + remote_access_lcd_data_out_reg = 2; + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 167; // Wait 40uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 7:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + // Display is now initialized + + // Send Function Set command + 8:begin + remote_access_lcd_data_out_reg = 2; + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 5; // Wait 1uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 9:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 10:begin + remote_access_lcd_data_out_reg = 8; + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 167; // Wait 40uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 11:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + + // Send Entry Mode Set command + 12:begin + remote_access_lcd_data_out_reg = 0; + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 5; // Wait 1uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 13:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 14:begin + remote_access_lcd_data_out_reg = 6; + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 167; // Wait 40uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 15:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + + // Send Display On command and disable cursors and blinking + 16:begin + remote_access_lcd_data_out_reg = 0; + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 5; // Wait 1uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 17:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 18:begin + remote_access_lcd_data_out_reg = 12; + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 167; // Wait 40uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 19:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + + // Send Clear Display command + 20:begin + remote_access_lcd_data_out_reg = 0; + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 5; // Wait 1uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 21:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 22:begin + remote_access_lcd_data_out_reg = 1; + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 6833; // Wait 1.64uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 23:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + + // Set DD RAM Address to 0 if lcd_display_line_two is 0, or 0x40 if it is 1 + 24:begin + remote_access_lcd_rs_out_reg = 0; + if (lcd_display_line_two == 0) begin + remote_access_lcd_data_out_reg = 8; + end + if (lcd_display_line_two == 1) begin + remote_access_lcd_data_out_reg = 12; + end + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 5; // Wait 1uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 25:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 26:begin + remote_access_lcd_data_out_reg = 0; + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 167; // Wait 40uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 27:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + + // Display the characters + 28:begin + remote_access_lcd_data_out_reg = lcd_display_string[lcd_display_current_character][7:4]; + remote_access_lcd_rs_out_reg = 1; + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 5; // Wait 1uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 29:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 30:begin + remote_access_lcd_data_out_reg = lcd_display_string[lcd_display_current_character][3:0]; + remote_access_lcd_enable_out_reg = 1; + lcd_display_wait_counter = 167; // Wait 40uS + lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 31:begin + remote_access_lcd_enable_out_reg = 0; + lcd_display_wait_counter = lcd_display_wait_counter - 1; + if (lcd_display_wait_counter == 0) lcd_display_initialization_state = lcd_display_initialization_state + 1; + end + 32:begin + lcd_display_current_character = lcd_display_current_character + 1; + lcd_display_initialization_state = lcd_display_initialization_state + 1; + if (lcd_display_current_character < 32) begin + lcd_display_initialization_state = 28; + end + if (lcd_display_current_character == 16) begin + if (lcd_display_line_two == 0) begin + lcd_display_line_two = 1; + lcd_display_initialization_state = 24; + end + end + end + 33:begin + // End! + remote_access_lcd_rs_out_reg = 0; + remote_access_lcd_enable_out_reg = 0; + lcd_display_line_two = 0; + lcd_display_current_character = 0; + if (update_lcd_display == 1) begin + lcd_display_line_two = 0; + lcd_display_current_character = 0; + lcd_display_initialization_state = 24; + lcd_display_string[0] = received_lcd_display_string[0]; + lcd_display_string[1] = received_lcd_display_string[1]; + lcd_display_string[2] = received_lcd_display_string[2]; + lcd_display_string[3] = received_lcd_display_string[3]; + lcd_display_string[4] = received_lcd_display_string[4]; + lcd_display_string[5] = received_lcd_display_string[5]; + lcd_display_string[6] = received_lcd_display_string[6]; + lcd_display_string[7] = received_lcd_display_string[7]; + lcd_display_string[8] = received_lcd_display_string[8]; + lcd_display_string[9] = received_lcd_display_string[9]; + lcd_display_string[10] = received_lcd_display_string[10]; + lcd_display_string[11] = received_lcd_display_string[11]; + lcd_display_string[12] = received_lcd_display_string[12]; + lcd_display_string[13] = received_lcd_display_string[13]; + lcd_display_string[14] = received_lcd_display_string[14]; + lcd_display_string[15] = received_lcd_display_string[15]; + lcd_display_string[16] = received_lcd_display_string[16]; + lcd_display_string[17] = received_lcd_display_string[17]; + lcd_display_string[18] = received_lcd_display_string[18]; + lcd_display_string[19] = received_lcd_display_string[19]; + lcd_display_string[20] = received_lcd_display_string[20]; + lcd_display_string[21] = received_lcd_display_string[21]; + lcd_display_string[22] = received_lcd_display_string[22]; + lcd_display_string[23] = received_lcd_display_string[23]; + lcd_display_string[24] = received_lcd_display_string[24]; + lcd_display_string[25] = received_lcd_display_string[25]; + lcd_display_string[26] = received_lcd_display_string[26]; + lcd_display_string[27] = received_lcd_display_string[27]; + lcd_display_string[28] = received_lcd_display_string[28]; + lcd_display_string[29] = received_lcd_display_string[29]; + lcd_display_string[30] = received_lcd_display_string[30]; + lcd_display_string[31] = received_lcd_display_string[31]; + end + end + endcase + end +endmodule + +module async_receiver(clk, RxD, RxD_data_ready, RxD_data, RxD_endofpacket, RxD_idle); + input clk, RxD; + output RxD_data_ready; // onc clock pulse when RxD_data is valid + output [7:0] RxD_data; + + parameter ClkFrequency = 25000000; // 25MHz + parameter Baud = 115200; + + // We also detect if a gap occurs in the received stream of characters + // That can be useful if multiple characters are sent in burst + // so that multiple characters can be treated as a "packet" + output RxD_endofpacket; // one clock pulse, when no more data is received (RxD_idle is going high) + output RxD_idle; // no data is being received + + // Baud generator (we use 8 times oversampling) + parameter Baud8 = Baud*8; + parameter Baud8GeneratorAccWidth = 16; + wire [Baud8GeneratorAccWidth:0] Baud8GeneratorInc = ((Baud8<<(Baud8GeneratorAccWidth-7))+(ClkFrequency>>8))/(ClkFrequency>>7); + reg [Baud8GeneratorAccWidth:0] Baud8GeneratorAcc; + always @(posedge clk) Baud8GeneratorAcc <= Baud8GeneratorAcc[Baud8GeneratorAccWidth-1:0] + Baud8GeneratorInc; + wire Baud8Tick = Baud8GeneratorAcc[Baud8GeneratorAccWidth]; + + //////////////////////////// + reg [1:0] RxD_sync_inv; + always @(posedge clk) if(Baud8Tick) RxD_sync_inv <= {RxD_sync_inv[0], ~RxD}; + // we invert RxD, so that the idle becomes "0", to prevent a phantom character to be received at startup + + reg [1:0] RxD_cnt_inv; + reg RxD_bit_inv; + + always @(posedge clk) + if(Baud8Tick) + begin + if( RxD_sync_inv[1] && RxD_cnt_inv!=2'b11) RxD_cnt_inv <= RxD_cnt_inv + 2'h1; + else + if(~RxD_sync_inv[1] && RxD_cnt_inv!=2'b00) RxD_cnt_inv <= RxD_cnt_inv - 2'h1; + + if(RxD_cnt_inv==2'b00) RxD_bit_inv <= 1'b0; + else + if(RxD_cnt_inv==2'b11) RxD_bit_inv <= 1'b1; + end + + reg [3:0] state; + reg [3:0] bit_spacing; + + // "next_bit" controls when the data sampling occurs + // depending on how noisy the RxD is, different values might work better + // with a clean connection, values from 8 to 11 work + wire next_bit = (bit_spacing==4'd10); + + always @(posedge clk) + if(state==0) + bit_spacing <= 4'b0000; + else + if(Baud8Tick) + bit_spacing <= {bit_spacing[2:0] + 4'b0001} | {bit_spacing[3], 3'b000}; + + always @(posedge clk) + if(Baud8Tick) + case(state) + 4'b0000: if(RxD_bit_inv) state <= 4'b1000; // start bit found? + 4'b1000: if(next_bit) state <= 4'b1001; // bit 0 + 4'b1001: if(next_bit) state <= 4'b1010; // bit 1 + 4'b1010: if(next_bit) state <= 4'b1011; // bit 2 + 4'b1011: if(next_bit) state <= 4'b1100; // bit 3 + 4'b1100: if(next_bit) state <= 4'b1101; // bit 4 + 4'b1101: if(next_bit) state <= 4'b1110; // bit 5 + 4'b1110: if(next_bit) state <= 4'b1111; // bit 6 + 4'b1111: if(next_bit) state <= 4'b0001; // bit 7 + 4'b0001: if(next_bit) state <= 4'b0000; // stop bit + default: state <= 4'b0000; + endcase + + reg [7:0] RxD_data; + always @(posedge clk) + if(Baud8Tick && next_bit && state[3]) RxD_data <= {~RxD_bit_inv, RxD_data[7:1]}; + + reg RxD_data_ready; + always @(posedge clk) + begin + RxD_data_ready <= (Baud8Tick && next_bit && state==4'b0001 && ~RxD_bit_inv); // ready only if the stop bit is received + end + + reg [4:0] gap_count; + always @(posedge clk) if (state!=0) gap_count<=5'h00; else if(Baud8Tick & ~gap_count[4]) gap_count <= gap_count + 5'h01; + assign RxD_idle = gap_count[4]; + reg RxD_endofpacket; always @(posedge clk) RxD_endofpacket <= Baud8Tick & (gap_count==5'h0F); +endmodule + +module async_transmit(clk, TxD_start, TxD_data, TxD, TxD_busy, state); + input clk, TxD_start; + input [7:0] TxD_data; + output TxD, TxD_busy; + output [4:0] state; + parameter ClkFrequency = 25000000; // 25MHz + //parameter ClkFrequency = 50000000; // 50MHz + parameter Baud = 115200; + parameter RegisterInputData = 1; // in RegisterInputData mode, the input doesn't have to stay valid while the character is been transmitted + + // Baud generator + parameter BaudGeneratorAccWidth = 16; + reg [BaudGeneratorAccWidth:0] BaudGeneratorAcc; + `ifdef DEBUG + wire [BaudGeneratorAccWidth:0] BaudGeneratorInc = 17'h10000; + `else + wire [BaudGeneratorAccWidth:0] BaudGeneratorInc = ((Baud<<(BaudGeneratorAccWidth-4))+(ClkFrequency>>5))/(ClkFrequency>>4); + `endif + + wire BaudTick = BaudGeneratorAcc[BaudGeneratorAccWidth]; + wire TxD_busy; + always @(posedge clk) if(TxD_busy) BaudGeneratorAcc <= BaudGeneratorAcc[BaudGeneratorAccWidth-1:0] + BaudGeneratorInc; + + // Transmitter state machine + reg [4:0] state; + wire TxD_ready = (state==0); + assign TxD_busy = ~TxD_ready; + + reg [7:0] TxD_dataReg; + always @(posedge clk) if(TxD_ready & TxD_start) TxD_dataReg <= TxD_data; + wire [7:0] TxD_dataD = RegisterInputData ? TxD_dataReg : TxD_data; + + always @(posedge clk) begin + if (TxD_start == 0) state <= 5'b00000; + + case(state) + 5'b00000: if(TxD_start) state <= 5'b00001; + 5'b00001: if(BaudTick) state <= 5'b00100; + 5'b00100: if(BaudTick) state <= 5'b01000; // start + 5'b01000: if(BaudTick) state <= 5'b01001; // bit 0 + 5'b01001: if(BaudTick) state <= 5'b01010; // bit 1 + 5'b01010: if(BaudTick) state <= 5'b01011; // bit 2 + 5'b01011: if(BaudTick) state <= 5'b01100; // bit 3 + 5'b01100: if(BaudTick) state <= 5'b01101; // bit 4 + 5'b01101: if(BaudTick) state <= 5'b01110; // bit 5 + 5'b01110: if(BaudTick) state <= 5'b01111; // bit 6 + 5'b01111: if(BaudTick) state <= 5'b00010; // bit 7 + 5'b00010: if(BaudTick) state <= 5'b00011; // stop1 + //4'b0011: if(BaudTick) state <= 4'b0000; // stop2 + 5'b00011: if(BaudTick) state <= 5'b10000; // stop2 + //default: if(BaudTick) state <= 4'b0000; + endcase + end + + // Output mux + reg muxbit; + always @( * ) + case(state[2:0]) + 3'd0: muxbit <= TxD_dataD[0]; + 3'd1: muxbit <= TxD_dataD[1]; + 3'd2: muxbit <= TxD_dataD[2]; + 3'd3: muxbit <= TxD_dataD[3]; + 3'd4: muxbit <= TxD_dataD[4]; + 3'd5: muxbit <= TxD_dataD[5]; + 3'd6: muxbit <= TxD_dataD[6]; + 3'd7: muxbit <= TxD_dataD[7]; + endcase + + // Put together the start, data and stop bits + reg TxD; + always @(posedge clk) TxD <= (state<4) | (state[3] & muxbit) | state[4]; // register the output to make it glitch free + +endmodule diff --git a/fpga/serial/xilinx/digilent/spartan_3/remote_access.v b/fpga/serial/xilinx/digilent/spartan_3/remote_access.v new file mode 120000 index 0000000..ccde8db --- /dev/null +++ b/fpga/serial/xilinx/digilent/spartan_3/remote_access.v @@ -0,0 +1 @@ +../../../common/remote_access.v \ No newline at end of file diff --git a/fpga/serial/xilinx/digilent/spartan_3e/remote_access.v b/fpga/serial/xilinx/digilent/spartan_3e/remote_access.v new file mode 120000 index 0000000..ccde8db --- /dev/null +++ b/fpga/serial/xilinx/digilent/spartan_3e/remote_access.v @@ -0,0 +1 @@ +../../../common/remote_access.v \ No newline at end of file diff --git a/fpga/serial/xilinx/digilent/spartan_6/remote_access.v b/fpga/serial/xilinx/digilent/spartan_6/remote_access.v new file mode 120000 index 0000000..ccde8db --- /dev/null +++ b/fpga/serial/xilinx/digilent/spartan_6/remote_access.v @@ -0,0 +1 @@ +../../../common/remote_access.v \ No newline at end of file diff --git a/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/data_storage.v b/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/data_storage.v new file mode 100644 index 0000000..7c9fcb0 --- /dev/null +++ b/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/data_storage.v @@ -0,0 +1,33 @@ +`timescale 1ns / 1ps +////////////////////////////////////////////////////////////////////////////////// +// +// (c) 2013 Timothy Pearson, Raptor Engineering +// Released into the Public Domain +// +////////////////////////////////////////////////////////////////////////////////// + +module data_storage( + input clka, + input [7:0] dina, + input [(RAM_ADDR_BITS-1):0] addra, + input wea, + output reg [7:0] douta); + + parameter RAM_ADDR_BITS = 14; + parameter RAM_WIDTH = 8; + + // Xilinx specific directive + (* RAM_STYLE="BLOCK" *) + + reg [RAM_WIDTH-1:0] data_storage_ram [(2**RAM_ADDR_BITS)-1:0]; + + always @(posedge clka) begin + if (wea) begin + data_storage_ram[addra] <= dina; + douta <= dina; + end else begin + douta <= data_storage_ram[addra]; + end + end + +endmodule diff --git a/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf b/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf new file mode 100644 index 0000000..c9a68dd --- /dev/null +++ b/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf @@ -0,0 +1,8 @@ +# (c) 2013 Timothy Pearson, Raptor Engineering +# Released into the Public Domain + +NET "clk" LOC = "V10" | IOSTANDARD = "LVCMOS33"; +TIMESPEC TS_clk = PERIOD clk 100000 kHz; + +NET "serial_input" LOC = "T12" | IOSTANDARD = "LVCMOS33"; +NET "serial_output" LOC = "M10" | IOSTANDARD = "LVCMOS33"; diff --git a/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v b/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v new file mode 100644 index 0000000..b852a6d --- /dev/null +++ b/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v @@ -0,0 +1,330 @@ +`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 diff --git a/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/remote_access.v b/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/remote_access.v new file mode 120000 index 0000000..a018632 --- /dev/null +++ b/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/remote_access.v @@ -0,0 +1 @@ +../remote_access.v \ No newline at end of file diff --git a/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/s6_remotefpga_test.xise b/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/s6_remotefpga_test.xise new file mode 100644 index 0000000..45b9e22 --- /dev/null +++ b/fpga/serial/xilinx/digilent/spartan_6/s6_remotefpga_test/s6_remotefpga_test.xise @@ -0,0 +1,366 @@ + + + +
+ + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/fpga/xilinx/digilent/spartan_3/remote_access.v b/fpga/xilinx/digilent/spartan_3/remote_access.v deleted file mode 120000 index ccde8db..0000000 --- a/fpga/xilinx/digilent/spartan_3/remote_access.v +++ /dev/null @@ -1 +0,0 @@ -../../../common/remote_access.v \ No newline at end of file diff --git a/fpga/xilinx/digilent/spartan_3e/remote_access.v b/fpga/xilinx/digilent/spartan_3e/remote_access.v deleted file mode 120000 index ccde8db..0000000 --- a/fpga/xilinx/digilent/spartan_3e/remote_access.v +++ /dev/null @@ -1 +0,0 @@ -../../../common/remote_access.v \ No newline at end of file diff --git a/fpga/xilinx/digilent/spartan_6/remote_access.v b/fpga/xilinx/digilent/spartan_6/remote_access.v deleted file mode 120000 index ccde8db..0000000 --- a/fpga/xilinx/digilent/spartan_6/remote_access.v +++ /dev/null @@ -1 +0,0 @@ -../../../common/remote_access.v \ No newline at end of file diff --git a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/data_storage.v b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/data_storage.v deleted file mode 100644 index 7c9fcb0..0000000 --- a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/data_storage.v +++ /dev/null @@ -1,33 +0,0 @@ -`timescale 1ns / 1ps -////////////////////////////////////////////////////////////////////////////////// -// -// (c) 2013 Timothy Pearson, Raptor Engineering -// Released into the Public Domain -// -////////////////////////////////////////////////////////////////////////////////// - -module data_storage( - input clka, - input [7:0] dina, - input [(RAM_ADDR_BITS-1):0] addra, - input wea, - output reg [7:0] douta); - - parameter RAM_ADDR_BITS = 14; - parameter RAM_WIDTH = 8; - - // Xilinx specific directive - (* RAM_STYLE="BLOCK" *) - - reg [RAM_WIDTH-1:0] data_storage_ram [(2**RAM_ADDR_BITS)-1:0]; - - always @(posedge clka) begin - if (wea) begin - data_storage_ram[addra] <= dina; - douta <= dina; - end else begin - douta <= data_storage_ram[addra]; - end - end - -endmodule diff --git a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf deleted file mode 100644 index c9a68dd..0000000 --- a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf +++ /dev/null @@ -1,8 +0,0 @@ -# (c) 2013 Timothy Pearson, Raptor Engineering -# Released into the Public Domain - -NET "clk" LOC = "V10" | IOSTANDARD = "LVCMOS33"; -TIMESPEC TS_clk = PERIOD clk 100000 kHz; - -NET "serial_input" LOC = "T12" | IOSTANDARD = "LVCMOS33"; -NET "serial_output" LOC = "M10" | IOSTANDARD = "LVCMOS33"; diff --git a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v deleted file mode 100644 index b852a6d..0000000 --- a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v +++ /dev/null @@ -1,330 +0,0 @@ -`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 diff --git a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/remote_access.v b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/remote_access.v deleted file mode 120000 index a018632..0000000 --- a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/remote_access.v +++ /dev/null @@ -1 +0,0 @@ -../remote_access.v \ No newline at end of file diff --git a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/s6_remotefpga_test.xise b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/s6_remotefpga_test.xise deleted file mode 100644 index 45b9e22..0000000 --- a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/s6_remotefpga_test.xise +++ /dev/null @@ -1,366 +0,0 @@ - - - -
- - - - - - - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
-- cgit v1.2.3