gpio test clean up
diff --git a/verilog/dv/Makefile b/verilog/dv/Makefile
index 749e090..c3bdba4 100644
--- a/verilog/dv/Makefile
+++ b/verilog/dv/Makefile
@@ -19,7 +19,7 @@
.SUFFIXES:
.SILENT: clean all
-PATTERNS = wb_port risc_boot user_risc_boot user_uart user_uart1 user_qspi user_i2cm riscv_regress user_basic user_usb user_pwm user_timer user_uart_master uart_master user_sram_exec user_cache_bypass
+PATTERNS = wb_port risc_boot user_risc_boot user_uart user_uart1 user_qspi user_i2cm riscv_regress user_basic user_usb user_pwm user_timer user_uart_master uart_master user_sram_exec user_cache_bypass user_gpio
all: ${PATTERNS}
for i in ${PATTERNS}; do \
diff --git a/verilog/dv/user_gpio/user_gpio_tb.v b/verilog/dv/user_gpio/user_gpio_tb.v
index a9e5944..6bc0c7f 100644
--- a/verilog/dv/user_gpio/user_gpio_tb.v
+++ b/verilog/dv/user_gpio/user_gpio_tb.v
@@ -25,6 +25,8 @@
//// Description ////
//// This is a standalone test bench to validate the ////
//// gpio interfaface through External WB i/F. ////
+//// 1.gpio posedge & negedge interrupt generation ////
+//// 2.gpio as input and output ////
//// ////
//// To Do: ////
//// nothing ////
@@ -120,8 +122,110 @@
always #12.5 clock <= (clock === 1'b0);
+ /************* Port-A Mapping **********************************
+ * ********************************************************/
+
+ reg [7:0] port_a_out;
+ wire [7:0] port_a_in = 8'h0;
+
+ /************* Port-B Mapping **********************************
+ * Pin-14 PB0/CLKO/ICP1 digital_io[11]
+ * Pin-15 PB1/SS[1]OC1A(PWM3) digital_io[12]
+ * Pin-16 PB2/SS[0]/OC1B(PWM4) digital_io[13]
+ * Pin-17 PB3/MOSI/OC2A(PWM5) digital_io[14]
+ * Pin-18 PB4/MISO digital_io[15]
+ * Pin-19 PB5/SCK digital_io[16]
+ * Pin-9 PB6/XTAL1/TOSC1 digital_io[6]
+ * Pin-10 PB7/XTAL2/TOSC2 digital_io[7]
+ * ********************************************************/
+
+ reg [7:0] port_b_out;
+ wire [7:0] port_b_in = { io_out[7],
+ io_out[6],
+ io_out[16],
+ io_out[15],
+ io_out[14],
+ io_out[13],
+ io_out[12],
+ io_out[11]
+ };
+
+ assign { io_in[7],
+ io_in[6],
+ io_in[16],
+ io_in[15],
+ io_in[14],
+ io_in[13],
+ io_in[12],
+ io_in[11]
+ } = port_b_out;
+
+ /************* Port-C Mapping **********************************
+ * Pin-1 PC6/RESET* digital_io[0]
+ * Pin-23 PC0/ADC0 digital_io[18]/analog_io[11]
+ * Pin-24 PC1/ADC1 digital_io[19]/analog_io[12]
+ * Pin-25 PC2/ADC2 digital_io[20]/analog_io[13]
+ * Pin-26 PC3/ADC3 digital_io[21]/analog_io[14]
+ * Pin-27 PC4/ADC4/SDA digital_io[22]/analog_io[15]
+ * Pin-28 PC5/ADC5/SCL digital_io[23]/analog_io[16]
+ * ********************************************************/
+
+ reg [7:0] port_c_out;
+ wire [7:0] port_c_in = { 1'b0,
+ io_out[0],
+ io_out[23],
+ io_out[22],
+ io_out[21],
+ io_out[20],
+ io_out[19],
+ io_out[18]
+ };
+ assign { io_in[0],
+ io_in[23],
+ io_in[22],
+ io_in[21],
+ io_in[20],
+ io_in[19],
+ io_in[18]
+ } = port_c_out[6:0];
+
+
+ /************* Port-D Mapping **********************************
+ * Pin-2 PD0/RXD[0] digital_io[1]
+ * Pin-3 PD1/TXD[0] digital_io[2]
+ * Pin-4 PD2/RXD[1]/INT0 digital_io[3]
+ * Pin-5 PD3/INT1/OC2B(PWM0) digital_io[4]
+ * Pin-6 PD4/TXD[1] digital_io[5]
+ * Pin-11 PD5/SS[3]/OC0B(PWM1)/T1 digital_io[8]
+ * Pin-12 PD6/SS[2]/OC0A(PWM2)/AIN0 digital_io[9]/analog_io[2]
+ * Pin-13 PD7/A1N1 digital_io[10]/analog_io[3]
+ * ********************************************************/
+
+ reg [7:0] port_d_out;
+ wire [7:0] port_d_in = { io_out[10],
+ io_out[9],
+ io_out[8],
+ io_out[5],
+ io_out[4],
+ io_out[3],
+ io_out[2],
+ io_out[1]
+ };
+
+ assign { io_in[10],
+ io_in[9],
+ io_in[8],
+ io_in[5],
+ io_in[4],
+ io_in[3],
+ io_in[2],
+ io_in[1]
+ } = port_d_out;
+
+
+ /*****************************/
+
initial begin
- OneUsPeriod = 1;
clock = 0;
wbd_ext_cyc_i ='h0; // strobe/request
wbd_ext_stb_i ='h0; // strobe/request
@@ -135,35 +239,104 @@
initial begin
$dumpfile("simx.vcd");
$dumpvars(1, `TB_GLBL);
+ $dumpvars(0, `TB_GLBL.u_top.u_wb_host);
+ $dumpvars(0, `TB_GLBL.u_top.u_intercon);
$dumpvars(0, `TB_GLBL.u_top.u_pinmux);
end
`endif
initial begin
- $dumpon;
+ test_fail = 0;
#200; // Wait for reset removal
repeat (10) @(posedge clock);
$display("Monitor: Standalone User Risc Boot Test Started");
- // Remove Wb Reset
- wb_user_core_write('h3080_0000,'h1);
repeat (2) @(posedge clock);
#1;
- wb_user_core_write('h3080_0004,'h10); // Change the Bank Sel 10
+ wb_user_core_write(`ADDR_SPACE_WBHOST+`WBHOST_GLBL_CFG,'h1);
- // Remove the reset
- // Remove WB and SPI/UART Reset, Keep CORE under Reset
- wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GBL_CFG0,'h01F);
+ // Disable Multi func
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_MULTI_FUNC,'h000);
- // config 1us based on system clock - 1000/25ns = 40
- wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GBL_CFG1,39);
+ /************* GPIO As Output ******************/
+ $display("#####################################");
+ $display("Step-1: Testing GPIO As Output ");
+ // Set the Direction as Output
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_DSEL,'hFFFFFFFF);
+ // Set the GPIO Output data: 0x55555555
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_ODATA,'h55555555);
+ cmp_gpio_output(8'h55,8'h55,8'h55,8'h55);
- // Enable GPIO Interrupt
- wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GBL_INTR_MSK,'h8000);
+ // Set the GPIO Output data: 0xAAAAAAAA
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_ODATA,'hAAAAAAAA);
+ cmp_gpio_output(8'hAA,8'hAA,8'hAA,8'hAA);
- test_fail = 0;
+ // Set the GPIO Output data: 0x5A5A5A5A5A5A
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_ODATA,'h5A5A5A5A);
+ cmp_gpio_output(8'h5A,8'h5A,8'h5A,8'h5A);
+
+ // Set the GPIO Output data: 0xA5A5A5A5A5A5
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_ODATA,'hA5A5A5A5);
+ cmp_gpio_output(8'hA5,8'hA5,8'hA5,8'hA5);
+
+ /************* GPIO As Input ******************/
+ $display("#####################################");
+ $display("Step-2: Testing GPIO As Input ");
+ // Set the Direction as Input
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_DSEL,'h00000000);
+
+ cmp_gpio_input(8'h55,8'h55,8'h55,8'h55);
+ cmp_gpio_input(8'hAA,8'hAA,8'hAA,8'hAA);
+ cmp_gpio_input(8'h5A,8'h5A,8'h5A,8'h5A);
+ cmp_gpio_input(8'hA5,8'hA5,8'hA5,8'hA5);
+
+ /************* GPIO As Input & GPIO Pos edge Interrupt ******************/
+ $display("#####################################");
+ $display("Step-3: Testing GPIO As Posedge Interrupt ");
+ // Set the Direction as Input
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_DSEL,'h00000000);
+ // Set GPIO for posedge Interrupt
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_INTR_MASK,'hFFFFFFFF);
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_POS_INTR,'hFFFFFFFF);
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_NEG_INTR,'h00000000);
+
+ // Drive GPIO with 0x55
+ cmp_gpio_pos_intr(8'h55,8'h55,8'h55,8'h55);
+
+ // Drive GPIO with 0xAA
+ cmp_gpio_pos_intr(8'hAA,8'hAA,8'hAA,8'hAA);
+
+ // Drive GPIO with 0x5A
+ cmp_gpio_pos_intr(8'h5A,8'h5A,8'h5A,8'h5A);
+
+ // Drive GPIO with 0xA5
+ cmp_gpio_pos_intr(8'hA5,8'hA5,8'hA5,8'hA5);
+
+ repeat (200) @(posedge clock);
+ /************* GPIO As Input & GPIO NEG edge Interrupt ******************/
+ $display("#####################################");
+ $display("Step-3: Testing GPIO As Negedge Interrupt ");
+ // Set the Direction as Input
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_DSEL,'h00000000);
+ // Set GPIO for negedge Interrupt
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_INTR_MASK,'hFFFFFFFF);
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_POS_INTR,'h00000000);
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_NEG_INTR,'hFFFFFFFF);
+
+ // Drive GPIO with 0x55
+ cmp_gpio_neg_intr(8'h55,8'h55,8'h55,8'h55);
+
+ // Drive GPIO with 0xAA
+ cmp_gpio_neg_intr(8'hAA,8'hAA,8'hAA,8'hAA);
+
+ // Drive GPIO with 0x5A
+ cmp_gpio_neg_intr(8'h5A,8'h5A,8'h5A,8'h5A);
+
+ // Drive GPIO with 0xA5
+ cmp_gpio_neg_intr(8'hA5,8'hA5,8'hA5,8'hA5);
+
repeat (200) @(posedge clock);
@@ -188,9 +361,9 @@
end
initial begin
- wb_rst_i <= 1'b1;
+ wb_rst_i = 1'b1;
#100;
- wb_rst_i <= 1'b0; // Release reset
+ wb_rst_i = 1'b0; // Release reset
end
wire USER_VDD1V8 = 1'b1;
wire VSS = 1'b0;
@@ -274,6 +447,174 @@
end
endtask
+
+/***************************
+* Check the GPIO Output
+* **************************/
+
+task cmp_gpio_output;
+input [7:0] exp_port_a;
+input [7:0] exp_port_b;
+input [7:0] exp_port_c;
+input [7:0] exp_port_d;
+begin
+ // Wait for some cycle to reg to be written through wbbone host
+ repeat (20) @(posedge clock);
+
+ if((exp_port_a & 8'h00) != (port_a_in & 8'h00))
+ begin
+ $display("ERROR: PORT A Exp: %x Rxd: %x",exp_port_a & 8'h00,port_a_in & 8'h00);
+ `TB_GLBL.test_fail = 1;
+ end else begin
+ $display("STATYS: PORT A Data: %x Matched ",port_a_in & 8'h00);
+ end
+
+ if((exp_port_b & 8'hFF) != (port_b_in & 8'hFF))
+ begin
+ $display("ERROR: PORT B Exp: %x Rxd: %x",exp_port_b & 8'hFF,port_b_in & 8'hFF);
+ `TB_GLBL.test_fail = 1;
+ end else begin
+ $display("STATYS: PORT B Data: %x Matched ",port_b_in & 8'hFF);
+ end
+
+ if((exp_port_c & 8'h7F) != (port_c_in & 8'h7F))
+ begin
+ $display("ERROR: PORT C Exp: %x Rxd: %x",exp_port_c & 8'h7F,port_c_in & 8'h7F);
+ `TB_GLBL.test_fail = 1;
+ end else begin
+ $display("STATYS: PORT C Data: %x Matched ",port_c_in & 8'h7F);
+ end
+
+ if((exp_port_d & 8'hFF) != (port_d_in & 8'hFF))
+ begin
+ $display("ERROR: PORT D Exp: %x Rxd: %x",exp_port_d & 8'hFF,port_d_in & 8'hFF);
+ `TB_GLBL.test_fail = 1;
+ end else begin
+ $display("STATYS: PORT D Data: %x Matched ",port_d_in & 8'hFF);
+ end
+end
+endtask
+
+/***************************
+* Check the GPIO input
+* **************************/
+
+task cmp_gpio_input;
+input [7:0] port_a;
+input [7:0] port_b;
+input [7:0] port_c;
+input [7:0] port_d;
+begin
+ port_a_out = port_a;
+ port_b_out = port_b;
+ port_c_out = port_c;
+ port_d_out = port_d;
+
+ wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_IDATA,read_data,{port_d,port_c & 8'h7F,port_b,8'h0});
+end
+endtask
+
+
+// Check for posedge Interrupt
+task cmp_gpio_pos_intr;
+input [7:0] port_a;
+input [7:0] port_b;
+input [7:0] port_c;
+input [7:0] port_d;
+begin
+
+ // Drive GPIO with zero
+ cmp_gpio_input(8'h00,8'h00,8'h00,8'h00);
+
+ // Clear Global Interrupt
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GBL_INTR,'h00008000);
+
+ // Clear all the Interrupt
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_INTR_CLR,'hFFFFFFFF);
+
+ wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_INTR_STAT,read_data,32'h0);
+
+ // Drive Ports
+ cmp_gpio_input(port_d,port_c,port_b,port_a);
+
+
+ // Wait for Edge Detection
+ repeat (20) @(posedge clock);
+
+ // Drive GPIO with zero
+ cmp_gpio_input(8'h00,8'h00,8'h00,8'h00);
+
+ // Wait for Edge Detection
+ repeat (20) @(posedge clock);
+
+ // Check the GPIO Interrupt
+ wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_INTR_STAT,read_data,{port_d,port_c & 8'h7F,port_b,8'h0});
+
+ // Check The Global Interrupt
+ wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_GBL_INTR,read_data,32'h8000);
+
+ // Clear The GPIO Interrupt
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_INTR_CLR,32'hFFFFFFFF);
+
+ // Clear GPIO Interrupt
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GBL_INTR,'h8000);
+
+
+ // Check Interrupt are cleared
+ wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_GBL_INTR,read_data,32'h0);
+ wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_INTR_STAT,read_data,32'h0);
+
+end
+endtask
+
+// Check for negedge Interrupt
+task cmp_gpio_neg_intr;
+input [7:0] port_a;
+input [7:0] port_b;
+input [7:0] port_c;
+input [7:0] port_d;
+begin
+
+ // Drive GPIO with All One's
+ cmp_gpio_input(8'hFF,8'hFF,8'hFF,8'hFF);
+
+ // Clear Global Interrupt
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GBL_INTR,'h00008000);
+
+ // Clear all the Interrupt
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_INTR_CLR,'hFFFFFFFF);
+ wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_INTR_STAT,read_data,32'h0);
+
+ // Drive Ports
+ cmp_gpio_input(port_d,port_c,port_b,port_a);
+
+ // Wait for Edge Detection
+ repeat (20) @(posedge clock);
+
+ // Drive GPIO with All One's
+ cmp_gpio_input(8'hFF,8'hFF,8'hFF,8'hFF);
+
+ // Wait for Edge Detection
+ repeat (20) @(posedge clock);
+
+ // Neg edge interrupt is will compliment of input value
+ wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_INTR_STAT,read_data,{port_d ^ 8'hFF,(port_c ^ 8'hFF) & 8'h7F,port_b ^ 8'hFF,8'h0});
+
+ // Check The Global Interrupt
+ wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_GBL_INTR,read_data,32'h8000);
+
+ // Clear The GPIO Interrupt
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_INTR_CLR,32'hFFFFFFFF);
+
+ // Clear GPIO Interrupt
+ wb_user_core_write(`ADDR_SPACE_PINMUX+`PINMUX_GBL_INTR,'h8000);
+
+ // Check Interrupt are cleared
+ wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_GBL_INTR,read_data,32'h0);
+ wb_user_core_read_check(`ADDR_SPACE_PINMUX+`PINMUX_GPIO_INTR_STAT,read_data,32'h0);
+end
+endtask
+
task wb_user_core_write;
input [31:0] address;
input [31:0] data;
@@ -363,117 +704,6 @@
repeat (2) @(posedge clock);
end
endtask
-// GPIO Pin Mapping
-//Pin-1 PC6/RESET* digital_io[0]
-//Pin-2 PD0/RXD digital_io[1]
-//Pin-3 PD1/TXD digital_io[2]
-//Pin-4 PD2/INT0 digital_io[3]
-//Pin-5 PD3/INT1/OC2B(PWM0) digital_io[4]
-//Pin-6 PD4 digital_io[5]
-//Pin-9 PB6/XTAL1/TOSC1 digital_io[6]
-//Pin-10 PB7/XTAL2/TOSC2 digital_io[7]
-//Pin-11 PD5/OC0B(PWM1)/T1 digital_io[8]
-//Pin-12 PD6/OC0A(PWM2)/AIN0 digital_io[9] /analog_io[2]
-//Pin-13 PD7/A1N1 digital_io[10]/analog_io[3]
-//Pin-14 PB0/CLKO/ICP1 digital_io[11]
-//Pin-15 PB1/OC1A(PWM3) digital_io[12]
-//Pin-16 PB2/SS/OC1B(PWM4) digital_io[13]
-//Pin-17 PB3/MOSI/OC2A(PWM5) digital_io[14]
-//Pin-18 PB4/MISO digital_io[15]
-//Pin-19 PB5/SCK digital_io[16]
-//Pin-23 PC0/ADC0 digital_io[18]/analog_io[11]
-//Pin-24 PC1/ADC1 digital_io[19]/analog_io[12]
-//Pin-25 PC2/ADC2 digital_io[20]/analog_io[13]
-//Pin-26 PC3/ADC3 digital_io[21]/analog_io[14]
-//Pin-27 PC4/ADC4/SDA digital_io[22]/analog_io[15]
-//Pin-28 PC5/ADC5/SCL digital_io[23]/analog_io[16]
-
-// Generate GPIO out data
-
-task gen_gpio_out;
-input [31:0] datain;
-output [7:0] port_a_out;
-output [7:0] port_b_out;
-output [7:0] port_c_out;
-output [7:0] port_d_out;
-
-reg [7:0] port_a_out;
-reg [7:0] port_b_out;
-reg [7:0] port_c_out;
-reg [7:0] port_d_out;
-begin
- port_a_out ='h0;
- port_b_out ='h0;
- port_c_out ='h0;
- port_d_out ='h0;
-
- port_c_out[6] = datain[0];
- port_d_out[0] = datain[1];
- port_d_out[1] = datain[2];
- port_d_out[2] = datain[3];
- port_d_out[3] = datain[4];
- port_d_out[4] = datain[5];
- port_b_out[6] = datain[6];
- port_b_out[7] = datain[7];
- port_d_out[5] = datain[8];
- port_d_out[6] = datain[9];
- port_d_out[7] = datain[10];
- port_b_out[0] = datain[11];
- port_b_out[1] = datain[12];
- port_b_out[2] = datain[13];
- port_b_out[3] = datain[14];
- port_b_out[4] = datain[15];
- port_b_out[5] = datain[16];
- port_c_out[0] = datain[18];
- port_c_out[1] = datain[19];
- port_c_out[2] = datain[20];
- port_c_out[3] = datain[21];
- port_c_out[4] = datain[22];
- port_c_out[5] = datain[23];
-end
-endtask
-
-// generate expected gpio data out
-task exp_gpio_in;
-output [7:0] port_a_in;
-output [7:0] port_b_in;
-output [7:0] port_c_in;
-output [7:0] port_d_in;
-reg [7:0] port_a_in;
-reg [7:0] port_b_in;
-reg [7:0] port_c_in;
-reg [7:0] port_d_in;
-begin
- port_a_in ='h0;
- port_b_in ='h0;
- port_c_in ='h0;
- port_d_in ='h0;
-
- port_c_in[6] = io_out[0];
- port_d_in[0] = io_out[1];
- port_d_in[1] = io_out[2];
- port_d_in[2] = io_out[3];
- port_d_in[3] = io_out[4];
- port_d_in[4] = io_out[5];
- port_b_in[6] = io_out[6];
- port_b_in[7] = io_out[7];
- port_d_in[5] = io_out[8];
- port_d_in[6] = io_out[9];
- port_d_in[7] = io_out[10];
- port_b_in[0] = io_out[11];
- port_b_in[1] = io_out[12];
- port_b_in[2] = io_out[13];
- port_b_in[3] = io_out[14];
- port_b_in[4] = io_out[15];
- port_b_in[5] = io_out[16];
- port_c_in[0] = io_out[18];
- port_c_in[1] = io_out[19];
- port_c_in[2] = io_out[20];
- port_c_in[3] = io_out[21];
- port_c_in[4] = io_out[22];
- port_c_in[5] = io_out[23];
-end
-endtask
`ifdef GL