Corrected the counter/timer and made an enhancement to respond to a disable/enable sequence as a counter reset. Generated testbenches for both counter/timers.
diff --git a/verilog/dv/caravel/defs.h b/verilog/dv/caravel/defs.h index f777c39..68c2000 100644 --- a/verilog/dv/caravel/defs.h +++ b/verilog/dv/caravel/defs.h
@@ -24,59 +24,65 @@ #define reg_gpio_pd (*(volatile uint32_t*)0x2100000c) // Logic Analyzer (0x2200_0000) -#define reg_la0_data (*(volatile uint32_t*)0x22000000) -#define reg_la1_data (*(volatile uint32_t*)0x22000004) -#define reg_la2_data (*(volatile uint32_t*)0x22000008) -#define reg_la3_data (*(volatile uint32_t*)0x2200000c) +#define reg_la0_data (*(volatile uint32_t*)0x25000000) +#define reg_la1_data (*(volatile uint32_t*)0x25000004) +#define reg_la2_data (*(volatile uint32_t*)0x25000008) +#define reg_la3_data (*(volatile uint32_t*)0x2500000c) -#define reg_la0_ena (*(volatile uint32_t*)0x22000010) -#define reg_la1_ena (*(volatile uint32_t*)0x22000014) -#define reg_la2_ena (*(volatile uint32_t*)0x22000018) -#define reg_la3_ena (*(volatile uint32_t*)0x2200001c) +#define reg_la0_ena (*(volatile uint32_t*)0x25000010) +#define reg_la1_ena (*(volatile uint32_t*)0x25000014) +#define reg_la2_ena (*(volatile uint32_t*)0x25000018) +#define reg_la3_ena (*(volatile uint32_t*)0x2500001c) // Mega Project Control (0x2300_0000) -#define reg_mprj_datal (*(volatile uint32_t*)0x23000000) -#define reg_mprj_datah (*(volatile uint32_t*)0x23000004) -#define reg_mprj_xfer (*(volatile uint32_t*)0x23000008) +#define reg_mprj_datal (*(volatile uint32_t*)0x26000000) +#define reg_mprj_datah (*(volatile uint32_t*)0x26000004) +#define reg_mprj_xfer (*(volatile uint32_t*)0x26000008) -#define reg_mprj_io_0 (*(volatile uint32_t*)0x2300000c) -#define reg_mprj_io_1 (*(volatile uint32_t*)0x23000010) -#define reg_mprj_io_2 (*(volatile uint32_t*)0x23000014) -#define reg_mprj_io_3 (*(volatile uint32_t*)0x23000018) -#define reg_mprj_io_4 (*(volatile uint32_t*)0x2300001c) -#define reg_mprj_io_5 (*(volatile uint32_t*)0x23000020) -#define reg_mprj_io_6 (*(volatile uint32_t*)0x23000024) +#define reg_mprj_io_0 (*(volatile uint32_t*)0x2600000c) +#define reg_mprj_io_1 (*(volatile uint32_t*)0x26000010) +#define reg_mprj_io_2 (*(volatile uint32_t*)0x26000014) +#define reg_mprj_io_3 (*(volatile uint32_t*)0x26000018) +#define reg_mprj_io_4 (*(volatile uint32_t*)0x2600001c) +#define reg_mprj_io_5 (*(volatile uint32_t*)0x26000020) +#define reg_mprj_io_6 (*(volatile uint32_t*)0x26000024) -#define reg_mprj_io_7 (*(volatile uint32_t*)0x23000028) -#define reg_mprj_io_8 (*(volatile uint32_t*)0x2300002c) -#define reg_mprj_io_9 (*(volatile uint32_t*)0x23000030) -#define reg_mprj_io_10 (*(volatile uint32_t*)0x23000034) +#define reg_mprj_io_7 (*(volatile uint32_t*)0x26000028) +#define reg_mprj_io_8 (*(volatile uint32_t*)0x2600002c) +#define reg_mprj_io_9 (*(volatile uint32_t*)0x26000030) +#define reg_mprj_io_10 (*(volatile uint32_t*)0x26000034) -#define reg_mprj_io_11 (*(volatile uint32_t*)0x23000038) -#define reg_mprj_io_12 (*(volatile uint32_t*)0x2300003c) -#define reg_mprj_io_13 (*(volatile uint32_t*)0x23000040) -#define reg_mprj_io_14 (*(volatile uint32_t*)0x23000044) +#define reg_mprj_io_11 (*(volatile uint32_t*)0x26000038) +#define reg_mprj_io_12 (*(volatile uint32_t*)0x2600003c) +#define reg_mprj_io_13 (*(volatile uint32_t*)0x26000040) +#define reg_mprj_io_14 (*(volatile uint32_t*)0x26000044) -#define reg_mprj_io_15 (*(volatile uint32_t*)0x23000048) -#define reg_mprj_io_16 (*(volatile uint32_t*)0x2300004c) -#define reg_mprj_io_17 (*(volatile uint32_t*)0x23000050) -#define reg_mprj_io_18 (*(volatile uint32_t*)0x23000054) +#define reg_mprj_io_15 (*(volatile uint32_t*)0x26000048) +#define reg_mprj_io_16 (*(volatile uint32_t*)0x2600004c) +#define reg_mprj_io_17 (*(volatile uint32_t*)0x26000050) +#define reg_mprj_io_18 (*(volatile uint32_t*)0x26000054) -#define reg_mprj_io_19 (*(volatile uint32_t*)0x23000058) -#define reg_mprj_io_20 (*(volatile uint32_t*)0x2300005c) -#define reg_mprj_io_21 (*(volatile uint32_t*)0x23000060) -#define reg_mprj_io_22 (*(volatile uint32_t*)0x23000064) +#define reg_mprj_io_19 (*(volatile uint32_t*)0x26000058) +#define reg_mprj_io_20 (*(volatile uint32_t*)0x2600005c) +#define reg_mprj_io_21 (*(volatile uint32_t*)0x26000060) +#define reg_mprj_io_22 (*(volatile uint32_t*)0x26000064) -#define reg_mprj_io_23 (*(volatile uint32_t*)0x23000068) -#define reg_mprj_io_24 (*(volatile uint32_t*)0x2300006c) -#define reg_mprj_io_25 (*(volatile uint32_t*)0x23000070) -#define reg_mprj_io_26 (*(volatile uint32_t*)0x23000074) +#define reg_mprj_io_23 (*(volatile uint32_t*)0x26000068) +#define reg_mprj_io_24 (*(volatile uint32_t*)0x2600006c) +#define reg_mprj_io_25 (*(volatile uint32_t*)0x26000070) +#define reg_mprj_io_26 (*(volatile uint32_t*)0x26000074) -#define reg_mprj_io_27 (*(volatile uint32_t*)0x23000078) -#define reg_mprj_io_28 (*(volatile uint32_t*)0x2300007c) -#define reg_mprj_io_29 (*(volatile uint32_t*)0x23000080) -#define reg_mprj_io_30 (*(volatile uint32_t*)0x23000084) -#define reg_mprj_io_31 (*(volatile uint32_t*)0x23000088) +#define reg_mprj_io_27 (*(volatile uint32_t*)0x26000078) +#define reg_mprj_io_28 (*(volatile uint32_t*)0x2600007c) +#define reg_mprj_io_29 (*(volatile uint32_t*)0x26000080) +#define reg_mprj_io_30 (*(volatile uint32_t*)0x26000084) +#define reg_mprj_io_31 (*(volatile uint32_t*)0x26000088) + +#define reg_mprj_io_32 (*(volatile uint32_t*)0x2600008c) +#define reg_mprj_io_33 (*(volatile uint32_t*)0x26000090) +#define reg_mprj_io_34 (*(volatile uint32_t*)0x26000094) +#define reg_mprj_io_35 (*(volatile uint32_t*)0x26000098) +#define reg_mprj_io_36 (*(volatile uint32_t*)0x2600009c) // Mega Project Slaves (0x3000_0000) #define reg_mprj_slave (*(volatile uint32_t*)0x30000000) @@ -85,18 +91,18 @@ #define reg_spictrl (*(volatile uint32_t*)0x2d000000) // Counter-Timer 0 Configuration -#define reg_timer0_config (*(volatile uint32_t*)0x21100000) -#define reg_timer0_value (*(volatile uint32_t*)0x21100004) -#define reg_timer0_data (*(volatile uint32_t*)0x21100008) +#define reg_timer0_config (*(volatile uint32_t*)0x22000000) +#define reg_timer0_value (*(volatile uint32_t*)0x22000004) +#define reg_timer0_data (*(volatile uint32_t*)0x22000008) // Counter-Timer 1 Configuration -#define reg_timer1_config (*(volatile uint32_t*)0x21200000) -#define reg_timer1_value (*(volatile uint32_t*)0x21200004) -#define reg_timer1_data (*(volatile uint32_t*)0x21200008) +#define reg_timer1_config (*(volatile uint32_t*)0x23000000) +#define reg_timer1_value (*(volatile uint32_t*)0x23000004) +#define reg_timer1_data (*(volatile uint32_t*)0x23000008) // SPI Master Configuration -#define reg_spimaster_config (*(volatile uint32_t*)0x21300000) -#define reg_spimaster_data (*(volatile uint32_t*)0x21300004) +#define reg_spimaster_config (*(volatile uint32_t*)0x24000000) +#define reg_spimaster_data (*(volatile uint32_t*)0x24000004) // System Area (0x2F00_0000) #define reg_pll_out_dest (*(volatile uint32_t*)0x2F00000c)
diff --git a/verilog/dv/caravel/mgmt_soc/Makefile b/verilog/dv/caravel/mgmt_soc/Makefile index b2e847d..2ab8056 100644 --- a/verilog/dv/caravel/mgmt_soc/Makefile +++ b/verilog/dv/caravel/mgmt_soc/Makefile
@@ -3,7 +3,7 @@ .SUFFIXES: .SILENT: clean all -PATTERNS = gpio mem uart perf hkspi sysctrl mprj_ctrl pass_thru timer +PATTERNS = gpio mem uart perf hkspi sysctrl mprj_ctrl pass_thru timer timer2 all: ${PATTERNS} for i in ${PATTERNS}; do \
diff --git a/verilog/dv/caravel/mgmt_soc/timer/timer.c b/verilog/dv/caravel/mgmt_soc/timer/timer.c index ed74567..131de72 100644 --- a/verilog/dv/caravel/mgmt_soc/timer/timer.c +++ b/verilog/dv/caravel/mgmt_soc/timer/timer.c
@@ -9,11 +9,23 @@ void main() { int i; + uint32_t value; - /* Set data out to zero */ - reg_mprj_datal = 0; + /* Initialize output data vector to zero */ + reg_mprj_datah = 0x00000000; + reg_mprj_datal = 0x00000000; - /* Lower 8 pins are input and upper 8 pins are output */ + /* Apply all 37 bits to management standard output. */ + + /* The lower 32 will be used to output the count value */ + /* from the timer. The top 5 bits will be used to mark */ + /* specific checkpoints for the testbench simulation. */ + + reg_mprj_io_36 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_35 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_34 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_33 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_32 = GPIO_MODE_MGMT_STD_OUTPUT; reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT; reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT; reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT; @@ -22,74 +34,89 @@ reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT; reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT; reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT; - - reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; - reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; - reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; - reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; - reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; - reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; - reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; - reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_NOPULL; + reg_mprj_io_23 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_22 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_21 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_20 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_15 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_14 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_13 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_12 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_11 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_10 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_9 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_8 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_7 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_6 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_5 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_4 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_3 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_2 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_1 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_0 = GPIO_MODE_MGMT_STD_OUTPUT; /* Apply configuration */ reg_mprj_xfer = 1; while (reg_mprj_xfer == 1); - // change the pull up and pull down (checked by the TB) - reg_mprj_datal = 0xa0000000; + /* Present start marker (see testbench verilog) */ + reg_mprj_datah = 0x0a; - reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; - reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; - reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; - reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; + /* Configure timer for a single-shot countdown */ + reg_timer0_value = 0xdcba9876; - reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; - reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; - reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; - reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; + /* Timer configuration bits: */ + /* 0 = timer enable (1 = enabled, 0 = disabled) */ + /* 1 = one-shot mode (1 = oneshot, 0 = continuous) */ + /* 2 = up/down (1 = count up, 0 = count down) */ + /* 3 = IRQ enable (1 = enabled, 0 = disabled) */ - /* Apply configuration */ - reg_mprj_xfer = 1; - while (reg_mprj_xfer == 1); + reg_timer0_config = 3; /* Enabled, one-shot, down count */ - reg_mprj_datal = 0x0b000000; - - reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; - reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; - reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; - reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; - - reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; - reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; - reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; - reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; - - /* Apply configuration */ - reg_mprj_xfer = 1; - while (reg_mprj_xfer == 1); - - reg_mprj_io_23 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; - reg_mprj_io_22 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; - reg_mprj_io_21 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; - reg_mprj_io_20 = GPIO_MODE_MGMT_STD_INPUT_PULLDOWN; - - reg_mprj_io_19 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; - reg_mprj_io_18 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; - reg_mprj_io_17 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; - reg_mprj_io_16 = GPIO_MODE_MGMT_STD_INPUT_PULLUP; - - /* Apply configuration */ - reg_mprj_xfer = 1; - while (reg_mprj_xfer == 1); - - // read the lower 8 pins, add 1 then output the result - // checked by the TB - reg_mprj_datal = 0xab000000; - - while (1){ - int x = (reg_mprj_datal & 0xff0000) >> 16; - reg_mprj_datal = (x+1) << 24; + for (i = 0; i < 8; i++) { + value = reg_timer0_data; + reg_mprj_datal = value; // Put count value on GPIO } + + reg_timer0_config = 0; /* Disabled */ + + reg_mprj_datah = 0x01; /* Check value in testbench */ + + reg_timer0_value = 0x00000011; + reg_timer0_config = 7; /* Enabled, one-shot, count up */ + + for (i = 0; i < 3; i++) { + value = reg_timer0_data; + reg_mprj_datal = value; // Put count value on GPIO + } + + reg_mprj_datah = 0x02; /* Check value in testbench */ + + reg_timer0_data = 0x00000101; // Set value (will be reset) + reg_timer0_config = 2; /* Disabled, one-shot, count up */ + reg_timer0_config = 5; /* Enabled, continuous, count down */ + + for (i = 0; i < 5; i++) { + value = reg_timer0_data; + reg_mprj_datal = value; // Put count value on GPIO + } + + reg_mprj_datah = 0x03; /* Check value in testbench */ + + reg_timer0_data = 0x00000145; // Force new value + + reg_mprj_datah = 0x04; /* Check value in testbench */ + + for (i = 0; i < 5; i++) { + value = reg_timer0_data; + reg_mprj_datal = value; // Put count value on GPIO + } + + /* Present end marker (see testbench verilog) */ + reg_mprj_datah = 0x05; }
diff --git a/verilog/dv/caravel/mgmt_soc/timer/timer_tb.v b/verilog/dv/caravel/mgmt_soc/timer/timer_tb.v index 0cc67fd..44b50db 100644 --- a/verilog/dv/caravel/mgmt_soc/timer/timer_tb.v +++ b/verilog/dv/caravel/mgmt_soc/timer/timer_tb.v
@@ -40,7 +40,7 @@ $dumpvars(0, timer_tb); // Repeat cycles of 1000 clock edges as needed to complete testbench - repeat (25) begin + repeat (50) begin repeat (1000) @(posedge clock); $display("+1000 cycles"); end @@ -51,13 +51,11 @@ end wire [36:0] mprj_io; // Most of these are no-connects - wire [15:0] checkbits; - reg [7:0] checkbits_lo; - wire [7:0] checkbits_hi; + wire [4:0] checkbits; + wire [31:0] countbits; - assign mprj_io[23:16] = checkbits_lo; - assign checkbits = mprj_io[31:16]; - assign checkbits_hi = checkbits[15:8]; + assign checkbits = mprj_io[36:32]; + assign countbits = mprj_io[31:0]; wire flash_csb; wire flash_clk; @@ -66,35 +64,44 @@ reg RSTB; - // Transactor - initial begin - checkbits_lo <= {8{1'bz}}; - wait(checkbits_hi == 8'hA0); - checkbits_lo <= 8'hF0; - wait(checkbits_hi == 8'h0B); - checkbits_lo <= 8'h0F; - wait(checkbits_hi == 8'hAB); - checkbits_lo <= 8'h0; - repeat (1000) @(posedge clock); - checkbits_lo <= 8'h1; - repeat (1000) @(posedge clock); - checkbits_lo <= 8'h3; - end - // Monitor initial begin - wait(checkbits_hi == 8'hA0); - wait(checkbits[7:0] == 8'hF0); - wait(checkbits_hi == 8'h0B); - wait(checkbits[7:0] == 8'h0F); - wait(checkbits_hi == 8'hAB); - wait(checkbits[7:0] == 8'h00); - wait(checkbits_hi == 8'h01); - wait(checkbits[7:0] == 8'h01); - wait(checkbits_hi == 8'h02); - wait(checkbits[7:0] == 8'h03); - wait(checkbits_hi == 8'h04); - $display("Monitor: Test GPIO (RTL) Passed"); + wait(checkbits == 5'h0a); + $display("Monitor: Test Timer (RTL) Started"); + + /* Add checks here */ + wait(checkbits == 5'h01); + $display(" countbits = 0x%x (should be 0xdcba7eb0)", countbits); + if(countbits !== 32'hdcba7eb0) begin + $display("Monitor: Test Timer (RTL) Failed"); + $finish; + end + wait(checkbits == 5'h02); + $display(" countbits = 0x%x (should be 0x10)", countbits); + if(countbits !== 32'h10) begin + $display("Monitor: Test Timer (RTL) Failed"); + $finish; + end + wait(checkbits == 5'h03); + $display(" countbits = %x (should be 0x0c)", countbits); + if(countbits !== 32'h0c) begin + $display("Monitor: Test Timer (RTL) Failed"); + $finish; + end + wait(checkbits == 5'h04); + $display(" countbits = %x (should be 0x0c)", countbits); + if(countbits !== 32'h0c) begin + $display("Monitor: Test Timer (RTL) Failed"); + $finish; + end + wait(checkbits == 5'h05); + $display(" countbits = %x (should be 0x117c)", countbits); + if(countbits !== 32'h117c) begin + $display("Monitor: Test Timer (RTL) Failed"); + $finish; + end + + $display("Monitor: Test Timer (RTL) Passed"); $finish; end @@ -107,8 +114,7 @@ end always @(checkbits) begin - #1 $display("GPIO state = %b (%d - %d)", checkbits, - checkbits_hi, checkbits_lo); + #1 $display("Timer state = %b (%d)", countbits, countbits); end wire VDD1V8;
diff --git a/verilog/dv/caravel/mgmt_soc/timer2/Makefile b/verilog/dv/caravel/mgmt_soc/timer2/Makefile new file mode 100644 index 0000000..6f00a38 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/timer2/Makefile
@@ -0,0 +1,40 @@ +FIRMWARE_PATH = ../.. +RTL_PATH = ../../../../rtl +IP_PATH = ../../../../ip +BEHAVIOURAL_MODELS = ../../ + +GCC_PATH=/ef/apps/bin + +.SUFFIXES: + +PATTERN = timer2 + +all: ${PATTERN:=.vcd} + +hex: ${PATTERN:=.hex} + +%.vvp: %_tb.v %.hex + iverilog -DFUNCTIONAL -I $(BEHAVIOURAL_MODELS)-I $(IP_PATH) -I $(RTL_PATH) \ + $< -o $@ + +%.vcd: %.vvp + vvp $< + +%.elf: %.c $(FIRMWARE_PATH)/sections.lds $(FIRMWARE_PATH)/start.s + ${GCC_PATH}/riscv32-unknown-elf-gcc -march=rv32imc -Wl,-Bstatic,-T,$(FIRMWARE_PATH)/sections.lds,--strip-debug -ffreestanding -nostdlib -o $@ $(FIRMWARE_PATH)/start.s $< + +%.hex: %.elf + ${GCC_PATH}/riscv32-unknown-elf-objcopy -O verilog $< $@ + # to fix flash base address + sed -i 's/@10000000/@00000000/g' $@ + +%.bin: %.elf + ${GCC_PATH}/riscv32-unknown-elf-objcopy -O binary $< /dev/stdout | tail -c +1048577 > $@ + +# ---- Clean ---- + +clean: + rm -f *.elf *.hex *.bin *.vvp *.vcd *.log + +.PHONY: clean hex all +
diff --git a/verilog/dv/caravel/mgmt_soc/timer2/timer2.c b/verilog/dv/caravel/mgmt_soc/timer2/timer2.c new file mode 100644 index 0000000..12c480f --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/timer2/timer2.c
@@ -0,0 +1,123 @@ +#include "../../defs.h" + +// -------------------------------------------------------- + +/* + * Timer2 Test --- This runs the same testbench as the + * other timer, on the 2nd counter/timer module instance. + */ + +void main() +{ + int i; + uint32_t value; + + /* Initialize output data vector to zero */ + reg_mprj_datah = 0x00000000; + reg_mprj_datal = 0x00000000; + + /* Apply all 37 bits to management standard output. */ + + /* The lower 32 will be used to output the count value */ + /* from the timer. The top 5 bits will be used to mark */ + /* specific checkpoints for the testbench simulation. */ + + reg_mprj_io_36 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_35 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_34 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_33 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_32 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_31 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_30 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_29 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_28 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_27 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_26 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_25 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_24 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_23 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_22 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_21 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_20 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_19 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_18 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_17 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_16 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_15 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_14 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_13 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_12 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_11 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_10 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_9 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_8 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_7 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_6 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_5 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_4 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_3 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_2 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_1 = GPIO_MODE_MGMT_STD_OUTPUT; + reg_mprj_io_0 = GPIO_MODE_MGMT_STD_OUTPUT; + + /* Apply configuration */ + reg_mprj_xfer = 1; + while (reg_mprj_xfer == 1); + + /* Present start marker (see testbench verilog) */ + reg_mprj_datah = 0x0a; + + /* Configure timer for a single-shot countdown */ + reg_timer1_value = 0xdcba9876; + + /* Timer configuration bits: */ + /* 0 = timer enable (1 = enabled, 0 = disabled) */ + /* 1 = one-shot mode (1 = oneshot, 0 = continuous) */ + /* 2 = up/down (1 = count up, 0 = count down) */ + /* 3 = IRQ enable (1 = enabled, 0 = disabled) */ + + reg_timer1_config = 3; /* Enabled, one-shot, down count */ + + for (i = 0; i < 8; i++) { + value = reg_timer1_data; + reg_mprj_datal = value; // Put count value on GPIO + } + + reg_timer1_config = 0; /* Disabled */ + + reg_mprj_datah = 0x01; /* Check value in testbench */ + + reg_timer1_value = 0x00000011; + reg_timer1_config = 7; /* Enabled, one-shot, count up */ + + for (i = 0; i < 3; i++) { + value = reg_timer1_data; + reg_mprj_datal = value; // Put count value on GPIO + } + + reg_mprj_datah = 0x02; /* Check value in testbench */ + + reg_timer1_data = 0x00000101; // Set value (will be reset) + reg_timer1_config = 2; /* Disabled, one-shot, count up */ + reg_timer1_config = 5; /* Enabled, continuous, count down */ + + for (i = 0; i < 5; i++) { + value = reg_timer1_data; + reg_mprj_datal = value; // Put count value on GPIO + } + + reg_mprj_datah = 0x03; /* Check value in testbench */ + + reg_timer1_data = 0x00000145; // Force new value + + reg_mprj_datah = 0x04; /* Check value in testbench */ + + for (i = 0; i < 5; i++) { + value = reg_timer1_data; + reg_mprj_datal = value; // Put count value on GPIO + } + + /* Present end marker (see testbench verilog) */ + reg_mprj_datah = 0x05; +} +
diff --git a/verilog/dv/caravel/mgmt_soc/timer2/timer2_tb.v b/verilog/dv/caravel/mgmt_soc/timer2/timer2_tb.v new file mode 100644 index 0000000..9c599a5 --- /dev/null +++ b/verilog/dv/caravel/mgmt_soc/timer2/timer2_tb.v
@@ -0,0 +1,174 @@ +/* + * StriVe - A full example SoC using PicoRV32 in SkyWater s8 + * + * Copyright (C) 2017 Clifford Wolf <clifford@clifford.at> + * Copyright (C) 2018 Tim Edwards <tim@efabless.com> + * + * Permission to use, copy, modify, and/or distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + */ + +`timescale 1 ns / 1 ps + +`include "caravel.v" +`include "spiflash.v" + +module timer2_tb; + wire VDD3V3; + assign VDD3V3 = 1'b1; + + reg clock; + + always #10 clock <= (clock === 1'b0); + + initial begin + clock <= 0; + end + + initial begin + $dumpfile("timer2.vcd"); + $dumpvars(0, timer2_tb); + + // Repeat cycles of 1000 clock edges as needed to complete testbench + repeat (50) begin + repeat (1000) @(posedge clock); + $display("+1000 cycles"); + end + $display("%c[1;31m",27); + $display ("Monitor: Timeout, Test GPIO (RTL) Failed"); + $display("%c[0m",27); + $finish; + end + + wire [36:0] mprj_io; // Most of these are no-connects + wire [4:0] checkbits; + wire [31:0] countbits; + + assign checkbits = mprj_io[36:32]; + assign countbits = mprj_io[31:0]; + + wire flash_csb; + wire flash_clk; + wire flash_io0; + wire flash_io1; + + reg RSTB; + + // Monitor + initial begin + wait(checkbits == 5'h0a); + $display("Monitor: Test Timer (RTL) Started"); + + /* Add checks here */ + wait(checkbits == 5'h01); + $display(" countbits = 0x%x (should be 0xdcba7eb0)", countbits); + if(countbits !== 32'hdcba7eb0) begin + $display("Monitor: Test Timer (RTL) Failed"); + $finish; + end + wait(checkbits == 5'h02); + $display(" countbits = 0x%x (should be 0x10)", countbits); + if(countbits !== 32'h10) begin + $display("Monitor: Test Timer (RTL) Failed"); + $finish; + end + wait(checkbits == 5'h03); + $display(" countbits = %x (should be 0x0c)", countbits); + if(countbits !== 32'h0c) begin + $display("Monitor: Test Timer (RTL) Failed"); + $finish; + end + wait(checkbits == 5'h04); + $display(" countbits = %x (should be 0x0c)", countbits); + if(countbits !== 32'h0c) begin + $display("Monitor: Test Timer (RTL) Failed"); + $finish; + end + wait(checkbits == 5'h05); + $display(" countbits = %x (should be 0x117c)", countbits); + if(countbits !== 32'h117c) begin + $display("Monitor: Test Timer (RTL) Failed"); + $finish; + end + + $display("Monitor: Test Timer (RTL) Passed"); + $finish; + end + + initial begin + RSTB <= 1'b0; + + #1000; + RSTB <= 1'b1; // Release reset + #2000; + end + + always @(checkbits) begin + #1 $display("Timer state = %b (%d)", countbits, countbits); + end + + wire VDD1V8; + wire VSS; + + assign VSS = 1'b0; + assign VDD1V8 = 1'b1; + + // These are the mappings of mprj_io GPIO pads that are set to + // specific functions on startup: + // + // JTAG = mgmt_gpio_io[0] (inout) + // SDO = mgmt_gpio_io[1] (output) + // SDI = mgmt_gpio_io[2] (input) + // CSB = mgmt_gpio_io[3] (input) + // SCK = mgmt_gpio_io[4] (input) + // ser_rx = mgmt_gpio_io[5] (input) + // ser_tx = mgmt_gpio_io[6] (output) + // irq = mgmt_gpio_io[7] (input) + + caravel uut ( + .vddio (VDD3V3), + .vssio (VSS), + .vdda (VDD3V3), + .vssa (VSS), + .vccd (VDD1V8), + .vssd (VSS), + .vdda1 (VDD3V3), + .vdda2 (VDD3V3), + .vssa1 (VSS), + .vssa2 (VSS), + .vccd1 (VDD1V8), + .vccd2 (VDD1V8), + .vssd1 (VSS), + .vssd2 (VSS), + .clock (clock), + .gpio (gpio), + .mprj_io (mprj_io), + .flash_csb(flash_csb), + .flash_clk(flash_clk), + .flash_io0(flash_io0), + .flash_io1(flash_io1), + .resetb (RSTB) + ); + + spiflash #( + .FILENAME("timer2.hex") + ) spiflash ( + .csb(flash_csb), + .clk(flash_clk), + .io0(flash_io0), + .io1(flash_io1), + .io2(), // not used + .io3() // not used + ); + +endmodule
diff --git a/verilog/rtl/counter_timer.v b/verilog/rtl/counter_timer.v index ccd1431..9e25281 100755 --- a/verilog/rtl/counter_timer.v +++ b/verilog/rtl/counter_timer.v
@@ -1,7 +1,7 @@ /* Simple 32-bit counter-timer for Caravel. */ module counter_timer_wb # ( - parameter BASE_ADR = 32'h2200_0000, + parameter BASE_ADR = 32'h2400_0000, parameter CONFIG = 8'h00, parameter VALUE = 8'h04, parameter DATA = 8'h08 @@ -85,6 +85,7 @@ reg irq_out; reg enable; // Enable (start) the counter/timer +reg lastenable; // Previous state of enable (catch rising/falling edge) reg oneshot; // Set oneshot (1) mode or continuous (0) mode reg updown; // Count up (1) or down (0) reg irq_ena; // Enable interrupt on timeout @@ -96,10 +97,12 @@ always @(posedge clkin or negedge resetn) begin if (resetn == 1'b0) begin enable <= 1'b0; + lastenable <= 1'b0; oneshot <= 1'b0; updown <= 1'b0; irq_ena <= 1'b0; end else begin + lastenable <= enable; if (reg_cfg_we) begin enable <= reg_cfg_di[0]; oneshot <= reg_cfg_di[1]; @@ -117,10 +120,10 @@ if (resetn == 1'b0) begin value_reset <= 32'd0; end else begin - if (reg_val_we[3]) value_reset <= reg_val_di[31:24]; - if (reg_val_we[2]) value_reset <= reg_val_di[23:16]; - if (reg_val_we[1]) value_reset <= reg_val_di[15:8]; - if (reg_val_we[0]) value_reset <= reg_val_di[7:0]; + if (reg_val_we[3]) value_reset[31:24] <= reg_val_di[31:24]; + if (reg_val_we[2]) value_reset[23:16] <= reg_val_di[23:16]; + if (reg_val_we[1]) value_reset[15:8] <= reg_val_di[15:8]; + if (reg_val_we[0]) value_reset[7:0] <= reg_val_di[7:0]; end end @@ -140,7 +143,9 @@ if (reg_dat_we[0] == 1'b1) value_cur[7:0] <= reg_dat_di[7:0]; end else if (enable == 1'b1) begin if (updown == 1'b1) begin - if (value_cur == value_reset) begin + if (lastenable == 1'b0) begin + value_cur <= 32'd0; + end else if (value_cur == value_reset) begin if (oneshot != 1'b1) begin value_cur <= 32'd0; end @@ -150,7 +155,9 @@ irq_out <= 1'b0; end end else begin - if (value_cur == 32'd0) begin + if (lastenable == 1'b0) begin + value_cur <= value_reset; + end else if (value_cur == 32'd0) begin if (oneshot != 1'b1) begin value_cur <= value_reset; end
diff --git a/verilog/rtl/housekeeping_spi.v b/verilog/rtl/housekeeping_spi.v index c6a4860..8ae1b81 100644 --- a/verilog/rtl/housekeeping_spi.v +++ b/verilog/rtl/housekeeping_spi.v
@@ -118,15 +118,16 @@ wire pass_thru_user_delay; wire loc_sdo; - // Pass-through mode handling + // Pass-through mode handling. Signals may only be applied when the + // core processor is in reset. - assign pass_thru_mgmt_csb = ~pass_thru_mgmt_delay; - assign pass_thru_mgmt_sck = pass_thru_mgmt ? SCK : 1'b0; - assign pass_thru_mgmt_sdi = pass_thru_mgmt ? SDI : 1'b0; + assign pass_thru_mgmt_csb = reset ? ~pass_thru_mgmt_delay : 1'bz; + assign pass_thru_mgmt_sck = reset ? (pass_thru_mgmt ? SCK : 1'b0) : 1'bz; + assign pass_thru_mgmt_sdi = reset ? (pass_thru_mgmt ? SDI : 1'b0) : 1'bz; - assign pass_thru_user_csb = ~pass_thru_user_delay; - assign pass_thru_user_sck = pass_thru_user ? SCK : 1'b0; - assign pass_thru_user_sdi = pass_thru_user ? SDI : 1'b0; + assign pass_thru_user_csb = reset ? ~pass_thru_user_delay : 1'bz; + assign pass_thru_user_sck = reset ? (pass_thru_user ? SCK : 1'b0) : 1'bz; + assign pass_thru_user_sdi = reset ? (pass_thru_user ? SDI : 1'b0) : 1'bz; assign SDO = pass_thru_mgmt ? pass_thru_mgmt_sdo : pass_thru_user ? pass_thru_user_sdo : loc_sdo;
diff --git a/verilog/rtl/mgmt_soc.v b/verilog/rtl/mgmt_soc.v index f6cf0f6..e5375ff 100644 --- a/verilog/rtl/mgmt_soc.v +++ b/verilog/rtl/mgmt_soc.v
@@ -153,14 +153,14 @@ parameter FLASH_BASE_ADR = 32'h 1000_0000; parameter UART_BASE_ADR = 32'h 2000_0000; parameter GPIO_BASE_ADR = 32'h 2100_0000; - parameter COUNTER_TIMER0_BASE_ADR = 32'h 2110_0000; - parameter COUNTER_TIMER1_BASE_ADR = 32'h 2120_0000; - parameter SPI_MASTER_BASE_ADR = 32'h 2130_0000; - parameter LA_BASE_ADR = 32'h 2200_0000; - parameter MPRJ_CTRL_ADR = 32'h 2300_0000; - parameter MPRJ_BASE_ADR = 32'h 3000_0000; // WB MI A - parameter SYS_BASE_ADR = 32'h 2F00_0000; + parameter COUNTER_TIMER0_BASE_ADR = 32'h 2200_0000; + parameter COUNTER_TIMER1_BASE_ADR = 32'h 2300_0000; + parameter SPI_MASTER_BASE_ADR = 32'h 2400_0000; + parameter LA_BASE_ADR = 32'h 2500_0000; + parameter MPRJ_CTRL_ADR = 32'h 2600_0000; parameter FLASH_CTRL_CFG = 32'h 2D00_0000; + parameter SYS_BASE_ADR = 32'h 2F00_0000; + parameter MPRJ_BASE_ADR = 32'h 3000_0000; // WB MI A parameter XBAR_BASE_ADR = 32'h 8000_0000; // UART