You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

331 lines
13 KiB

`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-1):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