diff --git a/fpga/gpmc/xilinx/common/logic_analyzer_data_storage.v b/fpga/gpmc/xilinx/common/logic_analyzer_data_storage.v
new file mode 100644
index 0000000..c5cae3c
--- /dev/null
+++ b/fpga/gpmc/xilinx/common/logic_analyzer_data_storage.v
@@ -0,0 +1,44 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+//
+// (c) 2014 Timothy Pearson, Raptor Engineering
+// Released into the Public Domain
+//
+//////////////////////////////////////////////////////////////////////////////////
+
+module logic_analyzer_data_storage(
+ input clka,
+ input clkb,
+ input [63:0] dina,
+ input [63:0] dinb,
+ input [8:0] addra,
+ input [8:0] addrb,
+ input wea,
+ input web,
+ output reg [63:0] douta,
+ output reg [63:0] doutb);
+
+ parameter RAM_WIDTH = 64;
+
+ // Xilinx specific directive
+ (* RAM_STYLE="BLOCK" *)
+
+ reg [RAM_WIDTH-1:0] data_storage_ram [(2**9)-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/common/main.v b/fpga/gpmc/xilinx/common/main.v
index a06565a..6d8c743 100644
--- a/fpga/gpmc/xilinx/common/main.v
+++ b/fpga/gpmc/xilinx/common/main.v
@@ -114,6 +114,26 @@ module main(
.wea(lcd_data_storage_wea), .web(lcd_data_storage_web),
.douta(lcd_data_storage_douta), .doutb(lcd_data_storage_doutb));
+ 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 [8:0] logic_analyzer_data_storage_addra;
+ reg [8:0] logic_analyzer_data_storage_addrb;
+ reg logic_analyzer_data_storage_wea;
+ reg logic_analyzer_data_storage_web;
+ wire [63:0] logic_analyzer_data_storage_douta;
+ wire [63:0] logic_analyzer_data_storage_doutb;
+
+ assign logic_analyzer_data_storage_clka = clk;
+ assign logic_analyzer_data_storage_clkb = 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
@@ -215,6 +235,47 @@ module main(
end
end
+ //-----------------------------------------------------------------------------------
+ //
+ // Logic analyzer
+ //
+ //-----------------------------------------------------------------------------------
+
+ reg logic_analyzer_trigger;
+ reg logic_analyzer_trigger_prev;
+ reg [9:0] logic_analyzer_address_counter;
+ always @(posedge clk) begin
+ // Trigger
+ logic_analyzer_trigger = ~userlogic_reset; // Trigger on userlogic_reset falling edge
+ if ((logic_analyzer_trigger == 1) && (logic_analyzer_trigger_prev == 0)) begin
+ logic_analyzer_address_counter = 0;
+ end
+
+ // Data load
+ if (logic_analyzer_address_counter < 9'b100000000) begin
+ logic_analyzer_data_storage_addrb = logic_analyzer_address_counter;
+
+ // Connect signals to logic analyzer
+ logic_analyzer_data_storage_dinb[3:0] = four_bit_leds;
+ logic_analyzer_data_storage_dinb[7:4] = four_bit_switches;
+ logic_analyzer_data_storage_dinb[15:8] = eight_bit_leds;
+ logic_analyzer_data_storage_dinb[23:16] = eight_bit_switches;
+ logic_analyzer_data_storage_dinb[27:24] = sseg_mux;
+ logic_analyzer_data_storage_dinb[35:28] = sseg_data;
+ logic_analyzer_data_storage_dinb[43:36] = usermem_data;
+ logic_analyzer_data_storage_dinb[59:44] = usermem_address;
+ logic_analyzer_data_storage_dinb[60] = usermem_wen;
+ logic_analyzer_data_storage_dinb[61] = usermem_wait;
+ logic_analyzer_data_storage_dinb[62] = 1'b0;
+ logic_analyzer_data_storage_dinb[63] = 1'b0;
+
+ logic_analyzer_data_storage_web = 1'b1;
+ logic_analyzer_address_counter = logic_analyzer_address_counter + 1;
+ end
+
+ logic_analyzer_trigger_prev = logic_analyzer_trigger;
+ end
+
//-----------------------------------------------------------------------------------
//
@@ -247,10 +308,12 @@ module main(
gpmc_address_reg = gpmc_address;
data_storage_write_enable = 1'b0;
lcd_data_storage_wea = 1'b0;
+ logic_analyzer_data_storage_wea = 1'b0;
end
if (gpmc_wen_reg == 1'b1) begin
data_storage_write_enable = 1'b0;
lcd_data_storage_wea = 1'b0;
+ logic_analyzer_data_storage_wea = 1'b0;
end
if (gpmc_address_reg[RAM_ADDR_BITS] == 1'b1) begin
@@ -320,8 +383,9 @@ module main(
// 0x0c: User device control
// Bit 0: User logic reset
// 0x20 - 0x3f: LCD data area
+ // 0x1000 - 0x1fff: Logic analyzer data area (read only)
if (gpmc_wen_reg == 1'b0) begin
- if (gpmc_address_reg[(RAM_ADDR_BITS-1):5] == 1) begin // Address range 0x20 - 0x3f
+ 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;
@@ -351,10 +415,39 @@ module main(
endcase
end
end else begin
- if (gpmc_address_reg[(RAM_ADDR_BITS-1):5] == 1) begin // Address range 0x20 - 0x3f
+ 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):12] == 1) begin // Address range 0x1000 - 0x1fff
+ logic_analyzer_data_storage_addra = gpmc_address_reg[12:3];
+ logic_analyzer_data_storage_wea = 1'b0;
+ case (gpmc_address_reg[2:0])
+ 0: begin
+ gpmc_data_out = logic_analyzer_data_storage_douta[7:0];
+ end
+ 1: begin
+ gpmc_data_out = logic_analyzer_data_storage_douta[15:8];
+ end
+ 2: begin
+ gpmc_data_out = logic_analyzer_data_storage_douta[23:16];
+ end
+ 3: begin
+ gpmc_data_out = logic_analyzer_data_storage_douta[31:24];
+ end
+ 4: begin
+ gpmc_data_out = logic_analyzer_data_storage_douta[39:32];
+ end
+ 5: begin
+ gpmc_data_out = logic_analyzer_data_storage_douta[47:40];
+ end
+ 6: begin
+ gpmc_data_out = logic_analyzer_data_storage_douta[55:48];
+ end
+ 7: begin
+ gpmc_data_out = logic_analyzer_data_storage_douta[63:56];
+ end
+ endcase
end else begin
case (gpmc_address_reg[(RAM_ADDR_BITS-1):0])
0: begin
diff --git a/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/logic_analyzer_data_storage.v b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/logic_analyzer_data_storage.v
new file mode 120000
index 0000000..1e8f72d
--- /dev/null
+++ b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/logic_analyzer_data_storage.v
@@ -0,0 +1 @@
+../../../common/logic_analyzer_data_storage.v
\ No newline at end of file
diff --git a/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/ulab_debug_interface.xise b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/ulab_debug_interface.xise
index 565fe9a..ac7f1e3 100644
--- a/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/ulab_debug_interface.xise
+++ b/fpga/gpmc/xilinx/numato/spartan6/xc6slx9/ulab_debug_interface.xise
@@ -17,18 +17,22 @@
-
+
-
+
-
+
+
+
+
+
@@ -93,6 +97,7 @@
+
@@ -326,7 +331,7 @@
-
+