diff options
Diffstat (limited to 'fpga')
| -rw-r--r-- | fpga/common/remote_access.v | 71 | ||||
| -rw-r--r-- | fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf | 6 | ||||
| -rw-r--r-- | fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v | 73 |
3 files changed, 117 insertions, 33 deletions
diff --git a/fpga/common/remote_access.v b/fpga/common/remote_access.v index 049b74f..668a6cc 100644 --- a/fpga/common/remote_access.v +++ b/fpga/common/remote_access.v @@ -43,7 +43,13 @@ module remote_access( output sram_available, input sram_processing_done, input [7:0] led_segment_bus, - input [3:0] led_digit_select); + 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); reg [7:0] remote_access_4_bit_input_reg; reg [7:0] remote_access_8_bit_input_reg; @@ -57,7 +63,7 @@ module remote_access( reg sram_available_reg; reg startup_needed = 1; - assign remote_access_4_bit_input = remote_access_4_bit_input_reg; + 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; @@ -77,6 +83,7 @@ module remote_access( 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; @@ -92,8 +99,12 @@ module remote_access( 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) begin + always @(posedge clk_div_by_two_oneeighty) begin clk_div_by_four = !clk_div_by_four; end @@ -108,45 +119,63 @@ module remote_access( //----------------------------------------------------------------------------------- reg [7:0] led_display_bytes [3:0]; - reg [4:0] digit_blanker_1 = 0; - reg [4:0] digit_blanker_2 = 0; - reg [4:0] digit_blanker_3 = 0; - reg [4:0] digit_blanker_4 = 0; + reg [5:0] digit_blanker_1 = 0; + reg [5:0] digit_blanker_2 = 0; + reg [5:0] digit_blanker_3 = 0; + reg [5: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 - if (led_digit_select[0] == 0) begin - led_display_bytes[0] = led_segment_bus; + 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[1] == 0) begin - led_display_bytes[1] = led_segment_bus; + 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[2] == 0) begin - led_display_bytes[2] = led_segment_bus; + 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[3] == 0) begin - led_display_bytes[3] = led_segment_bus; + 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 > 30) begin + + if (digit_blanker_1 > 60) begin led_display_bytes[0] = 255; end - if (digit_blanker_2 > 30) begin + if (digit_blanker_2 > 60) begin led_display_bytes[1] = 255; end - if (digit_blanker_3 > 30) begin + if (digit_blanker_3 > 60) begin led_display_bytes[2] = 255; end - if (digit_blanker_4 > 30) begin + if (digit_blanker_4 > 60) begin led_display_bytes[3] = 255; end end @@ -245,7 +274,7 @@ module remote_access( reg transmit_dsp_rx_complete = 0; reg transmit_dsp_rx_complete_done = 0; - // Transmit! + // 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; diff --git a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf index ab433e5..c9a68dd 100644 --- a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf +++ b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.ucf @@ -1,8 +1,8 @@ # (c) 2013 Timothy Pearson, Raptor Engineering # Released into the Public Domain -NET "clk" LOC = "V10"; +NET "clk" LOC = "V10" | IOSTANDARD = "LVCMOS33"; TIMESPEC TS_clk = PERIOD clk 100000 kHz; -NET "serial_input" LOC = "T12"; -NET "serial_output" LOC = "M10"; +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 index 801a9aa..6162ec1 100644 --- a/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v +++ b/fpga/xilinx/digilent/spartan_6/s6_remotefpga_test/main.v @@ -40,6 +40,9 @@ module main( 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;
//-------------------------------------------------------------------------------------------------------
//
@@ -69,9 +72,9 @@ module main( //
// Inputs:
// .clk: 50MHz clock
- // .4_bit_input 4-bit input to the user program from the remote access module
- // .8_bit_input 8-bit input to the user program from the remote access module
- // .16_bit_input 16-bit input to the user program from the remote access module
+ // .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
@@ -90,9 +93,9 @@ module main( // .led_digit_select Connect directly to the 4 bits enabling the LED display digits
//
// Outputs:
- // .4_bit_output 4-bit output from the user program to the remote access module
- // .8_bit_output 8-bit output from the user program to the remote access module
- // .16_bit_output 16-bit output from the user program to the remote access module
+ // .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
@@ -131,7 +134,7 @@ module main( .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(255), .led_digit_select(15));
+ .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
@@ -153,7 +156,8 @@ module main( 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));
+ .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));
//-------------------------------------------------------------------------------------------------------
//
@@ -174,7 +178,7 @@ endmodule //
//-------------------------------------------------------------------------------------------------------
-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);
+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;
@@ -188,6 +192,9 @@ module sample_demo(clk, four_bit_input, four_bit_output, eight_bit_input, eight_ 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
@@ -218,6 +225,54 @@ module sample_demo(clk, four_bit_input, four_bit_output, eight_bit_input, eight_ 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
//-------------------------------------------------------------------------------------------------------
|
