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.
646 lines
23 KiB
646 lines
23 KiB
`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,
|
|
output reg userlogic_reset,
|
|
input userlogic_clock,
|
|
|
|
output userlogic_serial_txd,
|
|
input userlogic_serial_rxd,
|
|
output host_serial_txd,
|
|
input host_serial_rxd,
|
|
|
|
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,
|
|
|
|
output userdevice_reset);
|
|
|
|
parameter RAM_ADDR_BITS = 15;
|
|
parameter CLKIN_PERIOD_NS = 10;
|
|
parameter LOGIC_ANALYZER_CLOCK_DIV = 2;
|
|
parameter LOGIC_ANALYZER_CLOCK_MULT = 2;
|
|
parameter LOGIC_ANALYZER_STEP = (CLKIN_PERIOD_NS*(LOGIC_ANALYZER_CLOCK_MULT/LOGIC_ANALYZER_CLOCK_DIV));
|
|
|
|
reg userdevice_reset_reg;
|
|
assign userdevice_reset = ~userdevice_reset_reg;
|
|
|
|
assign host_serial_txd = userlogic_serial_rxd;
|
|
assign userlogic_serial_txd = host_serial_rxd;
|
|
|
|
wire main_clk;
|
|
wire main_clk_online;
|
|
main_clock_generator main_clock_generator(.clkin(clk), .clkout(main_clk), .online(main_clk_online));
|
|
|
|
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 main_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 = 1'b0;
|
|
wire [7:0] data_storage_data_out;
|
|
|
|
assign data_storage_clka = main_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 = 1'b0;
|
|
reg lcd_data_storage_web = 1'b0;
|
|
wire [7:0] lcd_data_storage_douta;
|
|
wire [7:0] lcd_data_storage_doutb;
|
|
|
|
assign lcd_data_storage_clka = main_clk;
|
|
assign lcd_data_storage_clkb = main_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));
|
|
|
|
wire logic_analyzer_clk;
|
|
wire logic_analyzer_online;
|
|
//logic_analyzer_clock_generator #(LOGIC_ANALYZER_CLOCK_MULT, LOGIC_ANALYZER_CLOCK_DIV) logic_analyzer_clock_generator(.clkin(clk), .clkout(logic_analyzer_clk), .online(logic_analyzer_online));
|
|
// FIXME
|
|
// Work around block RAM problems
|
|
assign logic_analyzer_clk = main_clk;
|
|
assign logic_analyzer_online = 1'b1;
|
|
|
|
wire logic_analyzer_data_storage_clka;
|
|
wire logic_analyzer_data_storage_clkb;
|
|
reg [63:0] logic_analyzer_data_storage_dina;
|
|
reg [63:0] logic_analyzer_data_storage_dinb;
|
|
reg [10:0] logic_analyzer_data_storage_addra;
|
|
reg [10:0] logic_analyzer_data_storage_addrb;
|
|
reg logic_analyzer_data_storage_wea = 1'b0;
|
|
reg logic_analyzer_data_storage_web = 1'b0;
|
|
wire [63:0] logic_analyzer_data_storage_douta;
|
|
wire [63:0] logic_analyzer_data_storage_doutb;
|
|
|
|
assign logic_analyzer_data_storage_clka = logic_analyzer_clk;
|
|
assign logic_analyzer_data_storage_clkb = main_clk;
|
|
|
|
logic_analyzer_data_storage logic_analyzer_data_storage(.clka(logic_analyzer_data_storage_clka), .clkb(logic_analyzer_data_storage_clkb),
|
|
.dina(logic_analyzer_data_storage_dina), .dinb(logic_analyzer_data_storage_dinb),
|
|
.addra(logic_analyzer_data_storage_addra), .addrb(logic_analyzer_data_storage_addrb),
|
|
.wea(logic_analyzer_data_storage_wea), .web(logic_analyzer_data_storage_web),
|
|
.douta(logic_analyzer_data_storage_douta), .doutb(logic_analyzer_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 main_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'b1;
|
|
digit_blanker_3 = digit_blanker_3 + 1'b1;
|
|
digit_blanker_4 = digit_blanker_4 + 1'b1;
|
|
end
|
|
|
|
if (sseg_mux_latch[1] == 0) begin
|
|
led_display_bytes[1] = sseg_data_latch;
|
|
digit_blanker_1 = digit_blanker_1 + 1'b1;
|
|
digit_blanker_2 = 0;
|
|
digit_blanker_3 = digit_blanker_3 + 1'b1;
|
|
digit_blanker_4 = digit_blanker_4 + 1'b1;
|
|
end
|
|
|
|
if (sseg_mux_latch[2] == 0) begin
|
|
led_display_bytes[2] = sseg_data_latch;
|
|
digit_blanker_1 = digit_blanker_1 + 1'b1;
|
|
digit_blanker_2 = digit_blanker_2 + 1'b1;
|
|
digit_blanker_3 = 0;
|
|
digit_blanker_4 = digit_blanker_4 + 1'b1;
|
|
end
|
|
|
|
if (sseg_mux_latch[3] == 0) begin
|
|
led_display_bytes[3] = sseg_data_latch;
|
|
digit_blanker_1 = digit_blanker_1 + 1'b1;
|
|
digit_blanker_2 = digit_blanker_2 + 1'b1;
|
|
digit_blanker_3 = digit_blanker_3 + 1'b1;
|
|
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
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
//
|
|
// Logic analyzer
|
|
//
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
reg [32*8:0] logic_analyzer_signal_names [63:0];
|
|
|
|
initial begin
|
|
logic_analyzer_signal_names[0] <= "Four bit LEDs <0>\0";
|
|
logic_analyzer_signal_names[1] <= "Four bit LEDs <1>\0";
|
|
logic_analyzer_signal_names[2] <= "Four bit LEDs <2>\0";
|
|
logic_analyzer_signal_names[3] <= "Four bit LEDs <3>\0";
|
|
logic_analyzer_signal_names[4] <= "Four bit switches <0>\0";
|
|
logic_analyzer_signal_names[5] <= "Four bit switches <1>\0";
|
|
logic_analyzer_signal_names[6] <= "Four bit switches <2>\0";
|
|
logic_analyzer_signal_names[7] <= "Four bit switches <3>\0";
|
|
logic_analyzer_signal_names[8] <= "Eight bit LEDs <0>\0";
|
|
logic_analyzer_signal_names[9] <= "Eight bit LEDs <1>\0";
|
|
logic_analyzer_signal_names[10] <= "Eight bit LEDs <2>\0";
|
|
logic_analyzer_signal_names[11] <= "Eight bit LEDs <3>\0";
|
|
logic_analyzer_signal_names[12] <= "Eight bit LEDs <4>\0";
|
|
logic_analyzer_signal_names[13] <= "Eight bit LEDs <5>\0";
|
|
logic_analyzer_signal_names[14] <= "Eight bit LEDs <6>\0";
|
|
logic_analyzer_signal_names[15] <= "Eight bit LEDs <7>\0";
|
|
logic_analyzer_signal_names[16] <= "Eight bit switches <0>\0";
|
|
logic_analyzer_signal_names[17] <= "Eight bit switches <1>\0";
|
|
logic_analyzer_signal_names[18] <= "Eight bit switches <2>\0";
|
|
logic_analyzer_signal_names[19] <= "Eight bit switches <3>\0";
|
|
logic_analyzer_signal_names[20] <= "Eight bit switches <4>\0";
|
|
logic_analyzer_signal_names[21] <= "Eight bit switches <5>\0";
|
|
logic_analyzer_signal_names[22] <= "Eight bit switches <6>\0";
|
|
logic_analyzer_signal_names[23] <= "Eight bit switches <7>\0";
|
|
logic_analyzer_signal_names[24] <= "Seven-segment MUX <0>\0";
|
|
logic_analyzer_signal_names[25] <= "Seven-segment MUX <1>\0";
|
|
logic_analyzer_signal_names[26] <= "Seven-segment MUX <2>\0";
|
|
logic_analyzer_signal_names[27] <= "Seven-segment MUX <3>\0";
|
|
logic_analyzer_signal_names[28] <= "Seven-segment DATA <0>\0";
|
|
logic_analyzer_signal_names[29] <= "Seven-segment DATA <1>\0";
|
|
logic_analyzer_signal_names[30] <= "Seven-segment DATA <2>\0";
|
|
logic_analyzer_signal_names[31] <= "Seven-segment DATA <3>\0";
|
|
logic_analyzer_signal_names[32] <= "Seven-segment DATA <4>\0";
|
|
logic_analyzer_signal_names[33] <= "Seven-segment DATA <5>\0";
|
|
logic_analyzer_signal_names[34] <= "Seven-segment DATA <6>\0";
|
|
logic_analyzer_signal_names[35] <= "Seven-segment DATA <7>\0";
|
|
logic_analyzer_signal_names[36] <= "User memory DATA <0>\0";
|
|
logic_analyzer_signal_names[37] <= "User memory DATA <1>\0";
|
|
logic_analyzer_signal_names[38] <= "User memory DATA <2>\0";
|
|
logic_analyzer_signal_names[39] <= "User memory DATA <3>\0";
|
|
logic_analyzer_signal_names[40] <= "User memory DATA <4>\0";
|
|
logic_analyzer_signal_names[41] <= "User memory DATA <5>\0";
|
|
logic_analyzer_signal_names[42] <= "User memory DATA <6>\0";
|
|
logic_analyzer_signal_names[43] <= "User memory DATA <7>\0";
|
|
logic_analyzer_signal_names[44] <= "User memory ADDR <0>\0";
|
|
logic_analyzer_signal_names[45] <= "User memory ADDR <1>\0";
|
|
logic_analyzer_signal_names[46] <= "User memory ADDR <2>\0";
|
|
logic_analyzer_signal_names[47] <= "User memory ADDR <3>\0";
|
|
logic_analyzer_signal_names[48] <= "User memory ADDR <4>\0";
|
|
logic_analyzer_signal_names[49] <= "User memory ADDR <5>\0";
|
|
logic_analyzer_signal_names[50] <= "User memory ADDR <6>\0";
|
|
logic_analyzer_signal_names[51] <= "User memory ADDR <7>\0";
|
|
logic_analyzer_signal_names[52] <= "User memory ADDR <8>\0";
|
|
logic_analyzer_signal_names[53] <= "User memory ADDR <9>\0";
|
|
logic_analyzer_signal_names[54] <= "User memory ADDR <10>\0";
|
|
logic_analyzer_signal_names[55] <= "User memory ADDR <11>\0";
|
|
logic_analyzer_signal_names[56] <= "User memory ADDR <12>\0";
|
|
logic_analyzer_signal_names[57] <= "User memory ADDR <13>\0";
|
|
logic_analyzer_signal_names[58] <= "User memory ADDR <14>\0";
|
|
logic_analyzer_signal_names[59] <= "User memory ADDR <15>\0";
|
|
logic_analyzer_signal_names[60] <= "User memory WEN\0";
|
|
logic_analyzer_signal_names[61] <= "User memory WAIT\0";
|
|
logic_analyzer_signal_names[62] <= "GND REF\0";
|
|
logic_analyzer_signal_names[63] <= "User logic clock\0";
|
|
end
|
|
|
|
reg logic_analyzer_running = 1;
|
|
reg [15:0] logic_analyzer_timestep = LOGIC_ANALYZER_STEP;
|
|
reg [1:0] logic_analyzer_trigger = 2'b11;
|
|
reg [11:0] logic_analyzer_address_counter = 12'b100000000000;
|
|
always @(posedge logic_analyzer_clk) begin
|
|
// Trigger
|
|
logic_analyzer_trigger[1] = logic_analyzer_trigger[0];
|
|
logic_analyzer_trigger[0] = ~userlogic_reset; // Trigger on userlogic_reset falling edge
|
|
if ((logic_analyzer_running == 1) && (logic_analyzer_trigger[0] == 1) && (logic_analyzer_trigger[1] == 0)) begin
|
|
logic_analyzer_address_counter = 0;
|
|
end
|
|
|
|
// Data load
|
|
if (logic_analyzer_address_counter[11] == 1'b0) begin
|
|
// Set up write address
|
|
logic_analyzer_data_storage_addra <= logic_analyzer_address_counter[10:0];
|
|
|
|
// Connect signals to logic analyzer
|
|
logic_analyzer_data_storage_dina[3:0] <= four_bit_leds;
|
|
logic_analyzer_data_storage_dina[7:4] <= four_bit_switches;
|
|
logic_analyzer_data_storage_dina[15:8] <= eight_bit_leds;
|
|
logic_analyzer_data_storage_dina[23:16] <= eight_bit_switches;
|
|
logic_analyzer_data_storage_dina[27:24] <= sseg_mux;
|
|
logic_analyzer_data_storage_dina[35:28] <= sseg_data;
|
|
logic_analyzer_data_storage_dina[43:36] <= usermem_data;
|
|
logic_analyzer_data_storage_dina[59:44] <= usermem_address;
|
|
logic_analyzer_data_storage_dina[60] <= usermem_wen;
|
|
logic_analyzer_data_storage_dina[61] <= usermem_wait;
|
|
logic_analyzer_data_storage_dina[62] <= 1'b0; // UNUSED
|
|
logic_analyzer_data_storage_dina[63] <= userlogic_clock;
|
|
|
|
logic_analyzer_data_storage_wea <= 1'b1;
|
|
logic_analyzer_address_counter = logic_analyzer_address_counter + 1'b1;
|
|
end else begin
|
|
logic_analyzer_data_storage_addra <= 0;
|
|
logic_analyzer_data_storage_dina <= 0;
|
|
logic_analyzer_data_storage_wea <= 1'b0;
|
|
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 main_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;
|
|
// wen and advn are both verified before executing any write operations to avoid momentary wen glitches corrupting memory contents
|
|
if ((gpmc_wen_reg == 1'b0) && (gpmc_advn_reg == 1'b0)) begin
|
|
gpmc_data_reg <= gpmc_data;
|
|
end
|
|
if (gpmc_advn_reg == 1'b0) begin
|
|
gpmc_address_reg <= gpmc_address;
|
|
end
|
|
if (gpmc_wen_reg == 1'b1) begin
|
|
data_storage_write_enable <= 1'b0;
|
|
lcd_data_storage_wea <= 1'b0;
|
|
logic_analyzer_data_storage_web <= 1'b0;
|
|
end
|
|
gpmc_data_driven <= ((~gpmc_oen_reg) && gpmc_wen_reg);
|
|
|
|
if (gpmc_address_reg[RAM_ADDR_BITS] == 1'b1) begin
|
|
// System memory access
|
|
usermem_wait = 1'b1;
|
|
if ((gpmc_wen_reg == 1'b0) && (gpmc_advn_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)
|
|
// 0x0b: Number of address bits of DSP RAM (read only)
|
|
// 0x0c: User device control
|
|
// Bit 0: User logic reset
|
|
// Bit 1: User device reset
|
|
// 0x0d: Logic analyzer control
|
|
// Bit 0: Logic analyzer capture active
|
|
// Bit 7: Logic analyzer online (DCM locked) (read only)
|
|
// 0x0e: Logic analyzer timestep (ns) (upper 8 bits) (read only)
|
|
// 0x0f: Logic analyzer timestep (ns) (lower 8 bits) (read only)
|
|
// 0x20 - 0x3f: LCD data area
|
|
// 0x800 - 0xfff: Logic analyzer signal names area (read only)
|
|
// 0x4000 - 0x7fff: Logic analyzer data area (read only)
|
|
if ((gpmc_wen_reg == 1'b0) && (gpmc_advn_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 if (gpmc_address_reg[(RAM_ADDR_BITS-1):14] == 1) begin // Address range 0x4000 - 0x7fff
|
|
// FIXME
|
|
// Prevent incorrect operation of the block RAM by allowing the Port B write signal to be set under certain conditions
|
|
logic_analyzer_data_storage_addrb <= gpmc_address_reg[13:3];
|
|
logic_analyzer_data_storage_dinb[7:0] <= gpmc_data_reg;
|
|
logic_analyzer_data_storage_dinb[15:8] <= gpmc_data_reg;
|
|
logic_analyzer_data_storage_dinb[23:16] <= gpmc_data_reg;
|
|
logic_analyzer_data_storage_dinb[31:24] <= gpmc_data_reg;
|
|
logic_analyzer_data_storage_dinb[39:32] <= gpmc_data_reg;
|
|
logic_analyzer_data_storage_dinb[47:40] <= gpmc_data_reg;
|
|
logic_analyzer_data_storage_dinb[55:48] <= gpmc_data_reg;
|
|
logic_analyzer_data_storage_dinb[63:56] <= gpmc_data_reg;
|
|
logic_analyzer_data_storage_web <= 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
|
|
12: begin
|
|
userlogic_reset <= gpmc_data_reg[0];
|
|
userdevice_reset_reg <= gpmc_data_reg[1];
|
|
end
|
|
13: begin
|
|
logic_analyzer_running <= 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 if (gpmc_address_reg[(RAM_ADDR_BITS-1):11] == 1) begin // Address range 0x800 - 0xfff
|
|
gpmc_data_out <= logic_analyzer_signal_names[gpmc_address_reg[10:5]][(((32*8)-(gpmc_address_reg[4:0]*8))-1)-:8];
|
|
end else if (gpmc_address_reg[(RAM_ADDR_BITS-1):14] == 1) begin // Address range 0x4000 - 0x7fff
|
|
logic_analyzer_data_storage_addrb <= gpmc_address_reg[13:3];
|
|
logic_analyzer_data_storage_web <= 1'b0;
|
|
case (gpmc_address_reg[2:0])
|
|
0: begin
|
|
gpmc_data_out <= logic_analyzer_data_storage_doutb[63:56];
|
|
end
|
|
1: begin
|
|
gpmc_data_out <= logic_analyzer_data_storage_doutb[55:48];
|
|
end
|
|
2: begin
|
|
gpmc_data_out <= logic_analyzer_data_storage_doutb[47:40];
|
|
end
|
|
3: begin
|
|
gpmc_data_out <= logic_analyzer_data_storage_doutb[39:32];
|
|
end
|
|
4: begin
|
|
gpmc_data_out <= logic_analyzer_data_storage_doutb[31:24];
|
|
end
|
|
5: begin
|
|
gpmc_data_out <= logic_analyzer_data_storage_doutb[23:16];
|
|
end
|
|
6: begin
|
|
gpmc_data_out <= logic_analyzer_data_storage_doutb[15:8];
|
|
end
|
|
7: begin
|
|
gpmc_data_out <= logic_analyzer_data_storage_doutb[7:0];
|
|
end
|
|
endcase
|
|
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
|
|
11: begin
|
|
gpmc_data_out <= RAM_ADDR_BITS;
|
|
end
|
|
12: begin
|
|
gpmc_data_out[0] <= userlogic_reset;
|
|
gpmc_data_out[1] <= userdevice_reset_reg;
|
|
gpmc_data_out[7:2] <= 0;
|
|
end
|
|
13: begin
|
|
gpmc_data_out[0] <= logic_analyzer_running;
|
|
gpmc_data_out[6:1] <= 0;
|
|
gpmc_data_out[7] <= logic_analyzer_online;
|
|
end
|
|
14: begin
|
|
gpmc_data_out <= logic_analyzer_timestep[15:8];
|
|
end
|
|
15: begin
|
|
gpmc_data_out <= logic_analyzer_timestep[7:0];
|
|
end
|
|
default: begin
|
|
gpmc_data_out <= 0;
|
|
end
|
|
endcase
|
|
end
|
|
end
|
|
end
|
|
end
|
|
endmodule
|