summaryrefslogtreecommitdiffstats
path: root/fpga/gpmc/xilinx/common
diff options
context:
space:
mode:
Diffstat (limited to 'fpga/gpmc/xilinx/common')
-rw-r--r--fpga/gpmc/xilinx/common/data_storage.v19
-rw-r--r--fpga/gpmc/xilinx/common/lcd_data_storage.v28
-rw-r--r--fpga/gpmc/xilinx/common/logic_analyzer_data_storage.v53
-rw-r--r--fpga/gpmc/xilinx/common/main.v379
-rw-r--r--fpga/gpmc/xilinx/common/verification.v151
5 files changed, 475 insertions, 155 deletions
diff --git a/fpga/gpmc/xilinx/common/data_storage.v b/fpga/gpmc/xilinx/common/data_storage.v
index b98fb25..f4393a6 100644
--- a/fpga/gpmc/xilinx/common/data_storage.v
+++ b/fpga/gpmc/xilinx/common/data_storage.v
@@ -8,19 +8,20 @@
module data_storage(
input clka,
- input [7:0] dina,
+ input [(RAM_WIDTH-1):0] dina,
input [(RAM_ADDR_BITS-1):0] addra,
input wea,
- output reg [7:0] douta);
+ output reg [(RAM_WIDTH-1):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];
-
+
+ // Registered
always @(posedge clka) begin
if (wea) begin
data_storage_ram[addra] <= dina;
@@ -30,4 +31,12 @@ module data_storage(
end
end
+// // Unregistered
+// always @(posedge clka) begin
+// if (wea) begin
+// data_storage_ram[addra] <= dina;
+// end
+// end
+// assign douta = data_storage_ram[addra];
+
endmodule
diff --git a/fpga/gpmc/xilinx/common/lcd_data_storage.v b/fpga/gpmc/xilinx/common/lcd_data_storage.v
index c1f3559..8f7adac 100644
--- a/fpga/gpmc/xilinx/common/lcd_data_storage.v
+++ b/fpga/gpmc/xilinx/common/lcd_data_storage.v
@@ -23,22 +23,38 @@ module lcd_data_storage(
// Xilinx specific directive
(* RAM_STYLE="BLOCK" *)
- reg [RAM_WIDTH-1:0] data_storage_ram [(2**5)-1:0];
-
+ reg [RAM_WIDTH-1:0] lcd_data_storage_ram [(2**5)-1:0];
+
+ // Registered
always @(posedge clka) begin
- douta <= data_storage_ram[addra];
+ douta <= lcd_data_storage_ram[addra];
if (wea) begin
- data_storage_ram[addra] <= dina;
+ lcd_data_storage_ram[addra] <= dina;
douta <= dina;
end
end
always @(posedge clkb) begin
- doutb <= data_storage_ram[addrb];
+ doutb <= lcd_data_storage_ram[addrb];
if (web) begin
- data_storage_ram[addrb] <= dinb;
+ lcd_data_storage_ram[addrb] <= dinb;
doutb <= dinb;
end
end
+// // Unregistered
+// always @(posedge clka) begin
+// if (wea) begin
+// lcd_data_storage_ram[addra] <= dina;
+// end
+// end
+// assign douta = lcd_data_storage_ram[addra];
+//
+// always @(posedge clkb) begin
+// if (web) begin
+// lcd_data_storage_ram[addrb] <= dinb;
+// end
+// end
+// assign doutb = lcd_data_storage_ram[addrb];
+
endmodule
diff --git a/fpga/gpmc/xilinx/common/logic_analyzer_data_storage.v b/fpga/gpmc/xilinx/common/logic_analyzer_data_storage.v
index 1dd957e..a68d800 100644
--- a/fpga/gpmc/xilinx/common/logic_analyzer_data_storage.v
+++ b/fpga/gpmc/xilinx/common/logic_analyzer_data_storage.v
@@ -7,38 +7,63 @@
//////////////////////////////////////////////////////////////////////////////////
module logic_analyzer_data_storage(
- input clka,
- input clkb,
- input [63:0] dina,
- input [63:0] dinb,
- input [10:0] addra,
- input [10:0] addrb,
+ input clk,
+ input [(RAM_WIDTH-1):0] dina,
+ input [(RAM_WIDTH-1):0] dinb,
+ input [(RAM_ADDR_BITS-1):0] addra,
+ input [(RAM_ADDR_BITS-1):0] addrb,
input wea,
input web,
- output reg [63:0] douta,
- output reg [63:0] doutb);
+ output reg [(RAM_WIDTH-1):0] douta,
+ output reg [(RAM_WIDTH-1):0] doutb);
+ parameter RAM_ADDR_BITS = 11;
parameter RAM_WIDTH = 64;
// Xilinx specific directive
(* RAM_STYLE="BLOCK" *)
- reg [RAM_WIDTH-1:0] data_storage_ram [(2**11)-1:0];
-
+ reg [RAM_WIDTH-1:0] logic_analyzer_data_storage_ram [(2**RAM_ADDR_BITS)-1:0];
+
+ // Initial RAM values for debugging
+ integer index;
+ initial begin
+ for (index = 0; index < ((2**RAM_ADDR_BITS)-1); index = index + 2) begin
+ logic_analyzer_data_storage_ram[index+0] = {(RAM_WIDTH/4){4'ha}};
+ logic_analyzer_data_storage_ram[index+1] = {(RAM_WIDTH/4){4'h5}};
+ end
+ end
+
+ // Registered
always @(posedge clka) begin
- douta <= data_storage_ram[addra];
+ douta <= logic_analyzer_data_storage_ram[addra];
if (wea) begin
- data_storage_ram[addra] <= dina;
+ logic_analyzer_data_storage_ram[addra] <= dina;
douta <= dina;
end
end
always @(posedge clkb) begin
- doutb <= data_storage_ram[addrb];
+ doutb <= logic_analyzer_data_storage_ram[addrb];
if (web) begin
- data_storage_ram[addrb] <= dinb;
+ logic_analyzer_data_storage_ram[addrb] <= dinb;
doutb <= dinb;
end
end
+// // Unregistered
+// always @(posedge clka) begin
+// if (wea) begin
+// logic_analyzer_data_storage_ram[addra] <= dina;
+// end
+// end
+// assign douta = logic_analyzer_data_storage_ram[addra];
+//
+// always @(posedge clkb) begin
+// if (web) begin
+// logic_analyzer_data_storage_ram[addrb] <= dinb;
+// end
+// end
+// assign doutb = logic_analyzer_data_storage_ram[addrb];
+
endmodule
diff --git a/fpga/gpmc/xilinx/common/main.v b/fpga/gpmc/xilinx/common/main.v
index bf6e023..ef0df6b 100644
--- a/fpga/gpmc/xilinx/common/main.v
+++ b/fpga/gpmc/xilinx/common/main.v
@@ -63,6 +63,10 @@ module main(
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;
@@ -70,6 +74,10 @@ module main(
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;
@@ -77,7 +85,7 @@ module main(
assign sixteen_bit_io = (sixteen_bit_io_wen) ? sixteen_bit_io_out : 16'bz;
- always @(posedge clk) begin
+ 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
@@ -100,10 +108,10 @@ module main(
wire data_storage_clka;
reg [7:0] data_storage_dina;
reg [(RAM_ADDR_BITS-1):0] data_storage_addra;
- reg data_storage_write_enable;
+ reg data_storage_write_enable = 1'b0;
wire [7:0] data_storage_data_out;
- assign data_storage_clka = clk;
+ 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));
@@ -114,13 +122,13 @@ module main(
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;
+ 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 = clk;
- assign lcd_data_storage_clkb = clk;
+ 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),
@@ -129,7 +137,12 @@ module main(
.douta(lcd_data_storage_douta), .doutb(lcd_data_storage_doutb));
wire logic_analyzer_clk;
- logic_analyzer_clock_generator logic_analyzer_clock_generator(.clkin(clk), .clkout(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;
@@ -137,13 +150,13 @@ module main(
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;
- reg logic_analyzer_data_storage_web;
+ 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 = clk;
- assign logic_analyzer_data_storage_clkb = logic_analyzer_clk;
+ 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),
@@ -163,7 +176,7 @@ module main(
reg clk_div_by_eight;
reg clk_div_by_sixteen;
- always @(posedge clk) begin
+ always @(posedge main_clk) begin
clk_div_by_two = !clk_div_by_two;
end
@@ -206,32 +219,32 @@ module main(
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;
+ 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;
+ digit_blanker_1 = digit_blanker_1 + 1'b1;
digit_blanker_2 = 0;
- digit_blanker_3 = digit_blanker_3 + 1;
- digit_blanker_4 = digit_blanker_4 + 1;
+ 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;
- digit_blanker_2 = digit_blanker_2 + 1;
+ 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;
+ 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;
- digit_blanker_2 = digit_blanker_2 + 1;
- digit_blanker_3 = digit_blanker_3 + 1;
+ 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
@@ -258,39 +271,113 @@ module main(
//
//-----------------------------------------------------------------------------------
- reg logic_analyzer_trigger;
- reg logic_analyzer_trigger_prev;
- reg [11:0] logic_analyzer_address_counter;
+ 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 = ~userlogic_reset; // Trigger on userlogic_reset falling edge
- if ((logic_analyzer_trigger == 1) && (logic_analyzer_trigger_prev == 0)) begin
+ 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
- logic_analyzer_data_storage_addrb = logic_analyzer_address_counter;
+ // Set up write address
+ logic_analyzer_data_storage_addra <= logic_analyzer_address_counter[10:0];
// 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; // UNUSED
- logic_analyzer_data_storage_dinb[63] = userlogic_clock;
-
- logic_analyzer_data_storage_web = 1'b1;
- logic_analyzer_address_counter = logic_analyzer_address_counter + 1;
+ 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
-
- logic_analyzer_trigger_prev = logic_analyzer_trigger;
end
@@ -310,40 +397,39 @@ module main(
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;
- if (gpmc_wen_reg == 1'b0) begin
- gpmc_data_reg = gpmc_data;
+ 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;
- data_storage_write_enable = 1'b0;
- lcd_data_storage_wea = 1'b0;
- logic_analyzer_data_storage_wea = 1'b0;
+ 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_wea = 1'b0;
+ 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) begin
- data_storage_addra = gpmc_address_reg[(RAM_ADDR_BITS-1):0];
- data_storage_dina = gpmc_data_reg;
- data_storage_write_enable = 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;
+ 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
@@ -354,30 +440,30 @@ module main(
// 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;
+ 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;
+ 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;
+ 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;
+ 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;
+ 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
@@ -400,33 +486,55 @@ module main(
// 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) begin
+ 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;
+ 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];
+ four_bit_switches <= gpmc_data_reg[3:0];
end
3: begin
- eight_bit_switches = gpmc_data_reg;
+ eight_bit_switches <= gpmc_data_reg;
end
4: begin
- sixteen_bit_io_out[15:8] = gpmc_data_reg;
+ sixteen_bit_io_out[15:8] <= gpmc_data_reg;
end
5: begin
- sixteen_bit_io_out[7:0] = gpmc_data_reg;
+ sixteen_bit_io_out[7:0] <= gpmc_data_reg;
end
10: begin
- userproc_start = gpmc_data_reg[0];
+ userproc_start <= gpmc_data_reg[0];
end
12: begin
- userlogic_reset = gpmc_data_reg[0];
- userdevice_reset_reg = gpmc_data_reg[1];
+ 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
@@ -435,92 +543,103 @@ module main(
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;
+ 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_addra = gpmc_address_reg[13:3];
- logic_analyzer_data_storage_wea = 1'b0;
+ 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_douta[7:0];
+ gpmc_data_out <= logic_analyzer_data_storage_doutb[63:56];
end
1: begin
- gpmc_data_out = logic_analyzer_data_storage_douta[15:8];
+ gpmc_data_out <= logic_analyzer_data_storage_doutb[55:48];
end
2: begin
- gpmc_data_out = logic_analyzer_data_storage_douta[23:16];
+ gpmc_data_out <= logic_analyzer_data_storage_doutb[47:40];
end
3: begin
- gpmc_data_out = logic_analyzer_data_storage_douta[31:24];
+ gpmc_data_out <= logic_analyzer_data_storage_doutb[39:32];
end
4: begin
- gpmc_data_out = logic_analyzer_data_storage_douta[39:32];
+ gpmc_data_out <= logic_analyzer_data_storage_doutb[31:24];
end
5: begin
- gpmc_data_out = logic_analyzer_data_storage_douta[47:40];
+ gpmc_data_out <= logic_analyzer_data_storage_doutb[23:16];
end
6: begin
- gpmc_data_out = logic_analyzer_data_storage_douta[55:48];
+ gpmc_data_out <= logic_analyzer_data_storage_doutb[15:8];
end
7: begin
- gpmc_data_out = logic_analyzer_data_storage_douta[63:56];
+ 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;
+ gpmc_data_out <= 8'b01000010;
end
1: begin
- gpmc_data_out = 8'b00000001;
+ gpmc_data_out <= 8'b00000001;
end
2: begin
- gpmc_data_out[7:4] = 0;
- gpmc_data_out[3:0] = four_bit_leds;
+ gpmc_data_out[7:4] <= 0;
+ gpmc_data_out[3:0] <= four_bit_leds;
end
3: begin
- gpmc_data_out = eight_bit_leds;
+ gpmc_data_out <= eight_bit_leds;
end
4: begin
- gpmc_data_out = sixteen_bit_io_in[15:8];
+ gpmc_data_out <= sixteen_bit_io_in[15:8];
end
5: begin
- gpmc_data_out = sixteen_bit_io_in[7:0];
+ gpmc_data_out <= sixteen_bit_io_in[7:0];
end
6: begin
- gpmc_data_out = led_display_bytes[0];
+ gpmc_data_out <= led_display_bytes[0];
end
7: begin
- gpmc_data_out = led_display_bytes[1];
+ gpmc_data_out <= led_display_bytes[1];
end
8: begin
- gpmc_data_out = led_display_bytes[2];
+ gpmc_data_out <= led_display_bytes[2];
end
9: begin
- gpmc_data_out = led_display_bytes[3];
+ 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;
+ 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;
+ 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:1] = 0;
+ 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;
+ gpmc_data_out <= 0;
end
endcase
end
end
end
-
- gpmc_data_driven = ((~gpmc_oen) && gpmc_wen);
end
endmodule
diff --git a/fpga/gpmc/xilinx/common/verification.v b/fpga/gpmc/xilinx/common/verification.v
new file mode 100644
index 0000000..c871b26
--- /dev/null
+++ b/fpga/gpmc/xilinx/common/verification.v
@@ -0,0 +1,151 @@
+`timescale 1ns / 1ps
+//////////////////////////////////////////////////////////////////////////////////
+//
+// uLab GPMC interface verification test bench
+//
+// 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 verification;
+
+ // Inputs
+ reg clk;
+ reg gpmc_advn;
+ reg gpmc_oen;
+ reg gpmc_wen;
+ reg [15:0] gpmc_address;
+ reg usermem_wen;
+ reg userproc_done;
+ reg userlogic_clock;
+ reg userlogic_serial_rxd;
+ reg host_serial_rxd;
+ reg [3:0] four_bit_leds;
+ reg [7:0] eight_bit_leds;
+ reg sixteen_bit_io_wen;
+ reg [3:0] sseg_mux;
+ reg [7:0] sseg_data;
+
+ // Outputs
+ wire usermem_wait;
+ wire userproc_start;
+ wire userlogic_reset;
+ wire userlogic_serial_txd;
+ wire host_serial_txd;
+ wire [3:0] four_bit_switches;
+ wire [7:0] eight_bit_switches;
+ wire sixteen_bit_io_mode;
+ wire userdevice_reset;
+
+ // Bidirs
+ wire [7:0] gpmc_data;
+ wire [7:0] usermem_data;
+ wire [15:0] usermem_address;
+ wire [15:0] sixteen_bit_io;
+
+ // Instantiate the Unit Under Test (UUT)
+ main uut (
+ .clk(clk),
+ .gpmc_advn(gpmc_advn),
+ .gpmc_oen(gpmc_oen),
+ .gpmc_wen(gpmc_wen),
+ .gpmc_data(gpmc_data),
+ .gpmc_address(gpmc_address),
+ .usermem_wen(usermem_wen),
+ .usermem_wait(usermem_wait),
+ .usermem_data(usermem_data),
+ .usermem_address(usermem_address),
+ .userproc_start(userproc_start),
+ .userproc_done(userproc_done),
+ .userlogic_reset(userlogic_reset),
+ .userlogic_clock(userlogic_clock),
+ .userlogic_serial_txd(userlogic_serial_txd),
+ .userlogic_serial_rxd(userlogic_serial_rxd),
+ .host_serial_txd(host_serial_txd),
+ .host_serial_rxd(host_serial_rxd),
+ .four_bit_leds(four_bit_leds),
+ .eight_bit_leds(eight_bit_leds),
+ .four_bit_switches(four_bit_switches),
+ .eight_bit_switches(eight_bit_switches),
+ .sixteen_bit_io(sixteen_bit_io),
+ .sixteen_bit_io_wen(sixteen_bit_io_wen),
+ .sixteen_bit_io_mode(sixteen_bit_io_mode),
+ .sseg_mux(sseg_mux),
+ .sseg_data(sseg_data),
+ .userdevice_reset(userdevice_reset)
+ );
+
+ reg gpmc_data_driven = 0;
+ reg [7:0] gpmc_data_out;
+ assign gpmc_data = (gpmc_data_driven) ? gpmc_data_out : 8'bz;
+
+ // Generate 100MHz clock
+ always begin
+ #5;
+ clk = !clk;
+ end
+
+ // Terminate test bench after specified time has elapsed
+ initial begin
+ #10000;
+ $finish;
+ end
+
+ // Test logic analyzer triggering and data acquisition
+ initial begin
+ // Initialize Inputs
+ clk = 0;
+ gpmc_advn = 0;
+ gpmc_oen = 0;
+ gpmc_wen = 0;
+ gpmc_address = 0;
+ usermem_wen = 0;
+ userproc_done = 0;
+ userlogic_clock = 0;
+ userlogic_serial_rxd = 0;
+ host_serial_rxd = 0;
+ four_bit_leds = 0;
+ eight_bit_leds = 0;
+ sixteen_bit_io_wen = 0;
+ sseg_mux = 0;
+ sseg_data = 0;
+
+ // Wait 100 ns for global reset to finish
+ #100;
+
+ // Send user logic reset signal to GPMC interface
+ gpmc_address = 16'h000c;
+ gpmc_data_out = 8'h01;
+ gpmc_data_driven = 1'b1;
+ gpmc_advn = 1'b0;
+ gpmc_wen = 1'b0;
+ #1000
+ gpmc_address = 16'h000c;
+ gpmc_data_out = 8'h00;
+ gpmc_data_driven = 1'b1;
+ gpmc_advn = 1'b0;
+ gpmc_wen = 1'b0;
+ #100
+ gpmc_data_driven = 1'b0;
+ gpmc_advn = 1'b1;
+ gpmc_wen = 1'b1;
+ end
+
+endmodule
+