//-----------------------------------------------------------------------------
// customised example Cortex-M0 controller testbench with CPU trace for RTL or netlist
// A joint work commissioned on behalf of SoC Labs, under Arm Academic Access license.
//
// Contributors
//
// David Flynn (d.w.flynn@soton.ac.uk)
//
// Copyright © 2021-3, SoC Labs (www.soclabs.org)
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// The confidential and proprietary information contained in this file may
// only be used by a person authorised under and to the extent permitted
// by a subsisting licensing agreement from Arm Limited or its affiliates.
//
// (C) COPYRIGHT 2010-2013 Arm Limited or its affiliates.
// ALL RIGHTS RESERVED
//
// This entire notice must be reproduced on all copies of this file
// and copies of this file may only be made by a person if such person is
// permitted to do so under the terms of a subsisting license agreement
// from Arm Limited or its affiliates.
//
// SVN Information
//
// Checked In : $Date: 2017-10-10 15:55:38 +0100 (Tue, 10 Oct 2017) $
//
// Revision : $Revision: 371321 $
//
// Release Information : Cortex-M System Design Kit-r1p1-00rel0
//
//-----------------------------------------------------------------------------
//-----------------------------------------------------------------------------
// Abstract : Testbench for the Cortex-M0 example system
//-----------------------------------------------------------------------------
//
`timescale 1ns/1ps
module tb_cmsdk_mcu
;
wire XTAL1; // crystal pin 1
wire XTAL2; // crystal pin 2
wire NRST; // active low reset
wire [15:0] P0; // Port 0
wire [15:0] P1; // Port 1
wire VDDIO;
wire VSSIO;
wire VDD;
wire VSS;
//Debug tester signals
wire nTRST;
wire TDI;
wire SWDIOTMS;
wire SWCLKTCK;
wire TDO;
wire PCLK; // Clock for UART capture device
wire [5:0] debug_command; // used to drive debug tester
wire debug_running; // indicate debug test is running
wire debug_err; // indicate debug test has error
wire debug_test_en1;
wire debug_test_en2;
wire debug_test_en; // To enable the debug tester connection to MCU GPIO P0
// This signal is controlled by software,
// Use "UartPutc((char) 0x1B)" to send ESCAPE code to start
// the command, use "UartPutc((char) 0x11)" to send debug test
// enable command, use "UartPutc((char) 0x12)" to send debug test
// disable command. Refer to tb_uart_capture.v file for detail
assign debug_test_en = debug_test_en1 | debug_test_en2; // FT1248 or UART2 control
//-----------------------------------------
// System options
`define MEM_INIT 1;
localparam BE=0;
`define ARM_CMSDK_INCLUDE_DEBUG_TESTER 1
SROM_Ax32
#(.ADDRWIDTH (8),
.filename ("bootloader.hex"),
.romgen (1)
)
u_BOOTROM (
.CLK(XTAL1),
.ADDR(8'h0),
.SEL(1'b0),
.RDATA( )
);
// --------------------------------------------------------------------------------
// Cortex-M0/Cortex-M0+ Microcontroller
// --------------------------------------------------------------------------------
nanosoc_chip_pads
u_nanosoc_chip_pads (
`ifdef POWER_PINS
.VDDIO (VDDIO),
.VSSIO (VSSIO),
.VDD (VDD),
.VSS (VSS),
`endif
.XTAL1 (XTAL1), // input
.XTAL2 (XTAL2), // output
.NRST (NRST), // active low reset
.P0 (P0),
.P1 (P1),
.SWDIOTMS (SWDIOTMS),
.SWCLKTCK (SWCLKTCK)
);
// --------------------------------------------------------------------------------
// Source for clock and reset
// --------------------------------------------------------------------------------
cmsdk_clkreset u_cmsdk_clkreset(
.CLK (XTAL1),
.NRST (NRST)
);
// Pullup to suppress X-inputs
pullup(P0[ 0]);
pullup(P0[ 1]);
pullup(P0[ 2]);
pullup(P0[ 3]);
pullup(P0[ 4]);
pullup(P0[ 5]);
pullup(P0[ 6]);
pullup(P0[ 7]);
pullup(P0[ 8]);
pullup(P0[ 9]);
pullup(P0[10]);
pullup(P0[11]);
pullup(P0[12]);
pullup(P0[13]);
pullup(P0[14]);
pullup(P0[15]);
pullup(P1[ 0]);
pullup(P1[ 1]);
pullup(P1[ 2]);
pullup(P1[ 3]);
pullup(P1[ 4]);
pullup(P1[ 5]);
pullup(P1[ 6]);
pullup(P1[ 7]);
pullup(P1[ 8]);
pullup(P1[ 9]);
pullup(P1[10]);
pullup(P1[11]);
pullup(P1[12]);
pullup(P1[13]);
pullup(P1[14]);
pullup(P1[15]);
// --------------------------------------------------------------------------------
// UART output capture
// --------------------------------------------------------------------------------
`ifdef ARM_CMSDK_SLOWSPEED_PCLK
// If PCLK is running at slower speed, the UART output will also be slower
assign PCLK = u_cmsdk_mcu.u_cmsdk_mcu.PCLK;
`else
assign PCLK = XTAL1;
`endif
// --------------------------------------------------------------------------------
// external UART phase lock to (known) baud rate
// seem unable to use the following (due to generate instance naming?)
// wire baudx16_clk = u_cmsdk_mcu.u_cmsdk_mcu.u_cmsdk_mcu_system.u_apb_subsystem.u_apb_uart_2.BAUDTICK;
// 2000000/208 = 9615 baud (+0.16%)
// 208 / 16
`define BAUDPROG 130
reg [7:0] bauddiv;
wire baudclken = (bauddiv == 8'b00000000);
always @(negedge NRST or posedge PCLK)
if (!NRST)
bauddiv <=0;
else
bauddiv <= (baudclken) ? (`BAUDPROG-1) : (bauddiv -1) ; // count down of BAUDPROG
wire baudx16_clk = bauddiv[7]; //prefer:// !baudclken;
wire UARTXD = P1[5];
reg UARTXD_del;
always @(negedge NRST or posedge baudx16_clk)
if (!NRST)
UARTXD_del <= 1'b0;
else
UARTXD_del <= UARTXD; // delay one BAUD_TICK-time
wire UARTXD_edge = UARTXD_del ^ UARTXD; // edge detect
reg [3:0] pllq;
always @(negedge NRST or posedge baudx16_clk)
if (!NRST)
pllq[3:0] <= 4'b0000; // phase lock ready for Q[3] to go high
else
if (UARTXD_edge)
pllq[3:0] <= 4'b0110; // sync to mid bit-time
else
pllq[3:0] <= pllq[3:0] - 1; // count down divide-by-16
wire baud_clk = pllq[3];
reg baud_clk_del;
always @(negedge NRST or posedge PCLK)
if (!NRST)
baud_clk_del <= 1'b1;
else
baud_clk_del <= baud_clk;
// --------------------------------------------------------------------------------
// set FASTMODE true if UART simulation mode is programmed
wire FASTMODE = 1'b0;
wire uart_clk = (FASTMODE) ? PCLK : baud_clk; //(baud_clk & !baud_clk_del);
cmsdk_uart_capture #(.LOGFILENAME("uart2.log"))
u_cmsdk_uart_capture(
.RESETn (NRST),
.CLK (uart_clk), //PCLK),
.RXD (UARTXD), // UART 2 use for StdOut
.DEBUG_TESTER_ENABLE (debug_test_en2),
.SIMULATIONEND (), // This signal set to 1 at the end of simulation.
.AUXCTRL ()
);
// --------------------------------------------------------------------------------
// FTDI IO capture
// --------------------------------------------------------------------------------
// UART connection cross over for UART test
// assign P1[0] = P1[3]; // UART 0 RXD = UART 1 TXD
// assign P1[2] = P1[1]; // UART 1 RXD = UART 0 TXD
assign P1[4] = P1[5]; // loopback UART2
wire ft_clk_out = P1[1];
wire ft_miso_in;
assign P1[0] = ft_miso_in;
wire ft_ssn_out = P1[3];
// bufif0 (P1[2], ft_miosio_i, ft_miosio_z);
wire ft_clk2uart;
wire ft_rxd2uart;
wire ft_txd2uart;
cmsdk_ft1248x1_adpio // #(.ADPFILENAME("ADPFILENAME.log"))
u_ft1248_adpio(
.ft_clk_i (ft_clk_out),
.ft_ssn_i (ft_ssn_out),
.ft_miso_o (ft_miso_in),
.ft_miosio_io (P1[2]),
.FTDI_CLK2UART_o (ft_clk2uart),
.FTDI_OP2UART_o (ft_rxd2uart),
.FTDI_IP2UART_o (ft_txd2uart)
);
cmsdk_uart_capture #(.LOGFILENAME("ft1248_op.log"))
u_cmsdk_uart_capture1(
.RESETn (NRST),
.CLK (ft_clk2uart),
.RXD (ft_rxd2uart),
.DEBUG_TESTER_ENABLE (debug_test_en1),
.SIMULATIONEND (), // This signal set to 1 at the end of simulation.
.AUXCTRL ()
);
cmsdk_uart_capture #(.LOGFILENAME("ft1248_ip.log"))
u_cmsdk_uart_capture2(
.RESETn (NRST),
.CLK (ft_clk2uart),
.RXD (ft_txd2uart),
.DEBUG_TESTER_ENABLE ( ),
.SIMULATIONEND (), // This signal set to 1 at the end of simulation.
.AUXCTRL ()
);
// --------------------------------------------------------------------------------
// Tracking CPU with Tarmac trace support
// --------------------------------------------------------------------------------
`ifdef CORTEX_M0
`ifdef USE_TARMAC
`define ARM_CM0IK_PATH u_nanosoc_chip_pads.u_nanosoc_chip.u_nanosoc_cpu.u_cortex_m0_integration.u_cortexm0
CORTEXM0
#(.ACG(1), .AHBSLV(0), .BE(0), .BKPT(4),
.DBG(1), .NUMIRQ(32), .RAR(1), .SMUL(0),
.SYST(1), .WIC(1), .WICLINES(34), .WPT(2))
u_cortexm0_track
(
// Outputs
.HADDR ( ),
.HBURST ( ),
.HMASTLOCK ( ),
.HPROT ( ),
.HSIZE ( ),
.HTRANS ( ),
.HWDATA ( ),
.HWRITE ( ),
.HMASTER ( ),
.SLVRDATA ( ),
.SLVREADY ( ),
.SLVRESP ( ),
.DBGRESTARTED ( ),
.HALTED ( ),
.TXEV ( ),
.LOCKUP ( ),
.SYSRESETREQ ( ),
.CODENSEQ ( ),
.CODEHINTDE ( ),
.SPECHTRANS ( ),
.SLEEPING ( ),
.SLEEPDEEP ( ),
.SLEEPHOLDACKn ( ),
.WICDSACKn ( ),
.WICMASKISR ( ),
.WICMASKNMI ( ),
.WICMASKRXEV ( ),
.WICLOAD ( ),
.WICCLEAR ( ),
// Inputs
.SCLK (`ARM_CM0IK_PATH.SCLK),
.HCLK (`ARM_CM0IK_PATH.HCLK),
.DCLK (`ARM_CM0IK_PATH.DCLK),
.DBGRESETn (`ARM_CM0IK_PATH.DBGRESETn),
.HRESETn (`ARM_CM0IK_PATH.HRESETn),
.HRDATA (`ARM_CM0IK_PATH.HRDATA[31:0]),
.HREADY (`ARM_CM0IK_PATH.HREADY),
.HRESP (`ARM_CM0IK_PATH.HRESP),
.SLVADDR (`ARM_CM0IK_PATH.SLVADDR[31:0]),
.SLVSIZE (`ARM_CM0IK_PATH.SLVSIZE[1:0]),
.SLVTRANS (`ARM_CM0IK_PATH.SLVTRANS[1:0]),
.SLVWDATA (`ARM_CM0IK_PATH.SLVWDATA[31:0]),
.SLVWRITE (`ARM_CM0IK_PATH.SLVWRITE),
.DBGRESTART (`ARM_CM0IK_PATH.DBGRESTART),
.EDBGRQ (`ARM_CM0IK_PATH.EDBGRQ),
.NMI (`ARM_CM0IK_PATH.NMI),
.IRQ (`ARM_CM0IK_PATH.IRQ[31:0]),
.RXEV (`ARM_CM0IK_PATH.RXEV),
.STCALIB (`ARM_CM0IK_PATH.STCALIB[25:0]),
.STCLKEN (`ARM_CM0IK_PATH.STCLKEN),
.IRQLATENCY (`ARM_CM0IK_PATH.IRQLATENCY[7:0]),
.ECOREVNUM (`ARM_CM0IK_PATH.ECOREVNUM[19:0]),
.SLEEPHOLDREQn (`ARM_CM0IK_PATH.SLEEPHOLDREQn),
.WICDSREQn (`ARM_CM0IK_PATH.WICDSREQn),
.SE (`ARM_CM0IK_PATH.SE));
`define ARM_CM0IK_TRACK u_cortexm0_track
cm0_tarmac #(.LOGFILENAME("tarmac0.log"))
u_tarmac_track
(.enable_i (1'b1),
.hclk_i (`ARM_CM0IK_TRACK.HCLK),
.hready_i (`ARM_CM0IK_TRACK.HREADY),
.haddr_i (`ARM_CM0IK_TRACK.HADDR[31:0]),
.hprot_i (`ARM_CM0IK_TRACK.HPROT[3:0]),
.hsize_i (`ARM_CM0IK_TRACK.HSIZE[2:0]),
.hwrite_i (`ARM_CM0IK_TRACK.HWRITE),
.htrans_i (`ARM_CM0IK_TRACK.HTRANS[1:0]),
.hresetn_i (`ARM_CM0IK_TRACK.HRESETn),
.hresp_i (`ARM_CM0IK_TRACK.HRESP),
.hrdata_i (`ARM_CM0IK_TRACK.HRDATA[31:0]),
.hwdata_i (`ARM_CM0IK_TRACK.HWDATA[31:0]),
.lockup_i (`ARM_CM0IK_TRACK.LOCKUP),
.halted_i (`ARM_CM0IK_TRACK.HALTED),
.codehintde_i (`ARM_CM0IK_TRACK.CODEHINTDE[2:0]),
.codenseq_i (`ARM_CM0IK_TRACK.CODENSEQ),
.hdf_req_i (`ARM_CM0IK_TRACK.u_top.u_sys.ctl_hdf_request),
.int_taken_i (`ARM_CM0IK_TRACK.u_top.u_sys.dec_int_taken_o),
.int_return_i (`ARM_CM0IK_TRACK.u_top.u_sys.dec_int_return_o),
.int_pend_i (`ARM_CM0IK_TRACK.u_top.u_sys.nvm_int_pend),
.pend_num_i (`ARM_CM0IK_TRACK.u_top.u_sys.nvm_int_pend_num[5:0]),
.ipsr_i (`ARM_CM0IK_TRACK.u_top.u_sys.psr_ipsr[5:0]),
.ex_last_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.ctl_ex_last),
.iaex_en_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.ctl_iaex_en),
.reg_waddr_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.ctl_wr_addr[3:0]),
.reg_write_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.ctl_wr_en),
.xpsr_en_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.ctl_xpsr_en),
.fe_addr_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.pfu_fe_addr[30:0]),
.int_delay_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.pfu_int_delay),
.special_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.pfu_op_special),
.opcode_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.pfu_opcode[15:0]),
.reg_wdata_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.psr_gpr_wdata[31:0]),
.atomic_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_ctl.atomic),
.atomic_nxt_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_ctl.atomic_nxt),
.dabort_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_ctl.data_abort),
.ex_last_nxt_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_ctl.ex_last_nxt),
.int_preempt_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_ctl.int_preempt),
.psp_sel_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_gpr.psp_sel),
.xpsr_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_gpr.xpsr[31:0]),
.iaex_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_pfu.iaex[30:0]),
.iaex_nxt_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_pfu.iaex_nxt[30:0]),
.opcode_nxt_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_pfu.ibuf_de_nxt[15:0]),
.delay_count_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_pfu.ibuf_lo[13:6]),
.tbit_en_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_pfu.tbit_en),
.cflag_en_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_psr.cflag_ena),
.ipsr_en_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_psr.ipsr_ena),
.nzflag_en_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_psr.nzflag_ena),
.vflag_en_i (`ARM_CM0IK_TRACK.u_top.u_sys.u_core.u_psr.vflag_ena)
);
`endif // USE_TARMAC
`endif // CORTEX_M0
// --------------------------------------------------------------------------------
// Debug tester connection -
// --------------------------------------------------------------------------------
`ifdef ARM_CMSDK_INCLUDE_DEBUG_TESTER
// Add pullups and pulldowns on Debug Interface
pullup (nTRST);
pullup (TDI);
pullup (TDO);
pullup (SWDIOTMS);
pulldown (SWCLKTCK);
//connect to P0 for debug command and status pin
//add pulldown to debug command and debug status signals
// to give default value 0;
pulldown(debug_command[5]);
pulldown(debug_command[4]);
pulldown(debug_command[3]);
pulldown(debug_command[2]);
pulldown(debug_command[1]);
pulldown(debug_command[0]);
pulldown(debug_running);
pulldown(debug_err);
//Tristate logic for GPIO connection
bufif1 (debug_command[5], P0[29-16], debug_test_en);
bufif1 (debug_command[4], P0[28-16], debug_test_en);
bufif1 (debug_command[3], P0[27-16], debug_test_en);
bufif1 (debug_command[2], P0[26-16], debug_test_en);
bufif1 (debug_command[1], P0[25-16], debug_test_en);
bufif1 (debug_command[0], P0[24-16], debug_test_en);
bufif1 (P0[31-16], debug_running, debug_test_en);
bufif1 (P0[30-16], debug_err, debug_test_en);
cmsdk_debug_tester #(.ROM_MEMFILE((BE==1) ? "debugtester_be.hex" : "debugtester_le.hex"))
u_cmsdk_debug_tester
(
// Clock and Reset
.CLK (XTAL1),
.PORESETn (NRST),
// Command Interface
.DBGCMD (debug_command[5:0]),
.DBGRUNNING (debug_running),
.DBGERROR (debug_err),
// Trace Interface
.TRACECLK (1'b0),
.TRACEDATA (4'h0),
.SWV (1'b0),
// Debug Interface
.TDO (TDO),
.nTRST (nTRST),
.SWCLKTCK (SWCLKTCK),
.TDI (TDI),
.SWDIOTMS (SWDIOTMS)
);
`endif
// --------------------------------------------------------------------------------
// Misc
// --------------------------------------------------------------------------------
// Format for time reporting
initial $timeformat(-9, 0, " ns", 0);
// Configuration checks
initial begin
`ifdef CORTEX_M0DESIGNSTART
`ifdef CORTEX_M0
$display("ERROR (tb_cmsdk_mcu.v) in CPU preprocessing directive : Both CORTEX_M0DESIGNSTART and CORTEX_M0 are set. Please use only one.");
$stop;
`endif
`endif
`ifdef CORTEX_M0DESIGNSTART
`ifdef CORTEX_M0PLUS
$display("ERROR (tb_cmsdk_mcu.v) in CPU preprocessing directive : Both CORTEX_M0DESIGNSTART and CORTEX_M0PLUS are set. Please use only one.");
$stop;
`endif
`endif
`ifdef CORTEX_M0
`ifdef CORTEX_M0PLUS
$display("ERROR (tb_cmsdk_mcu.v) in CPU preprocessing directive : Both CORTEX_M0 and CORTEX_M0PLUS are set. Please use only one.");
$stop;
`endif
`endif
`ifdef CORTEX_M0DESIGNSTART
`ifdef CORTEX_M0
`ifdef CORTEX_M0PLUS
$display("ERROR (tb_cmsdk_mcu.v) in CPU preprocessing directive : All of CORTEX_M0DESIGNSTART, CORTEX_M0 and CORTEX_M0PLUS are set. Please use only one.");
$stop;
`endif
`endif
`endif
`ifdef CORTEX_M0
`else
`ifdef CORTEX_M0PLUS
`else
`ifdef CORTEX_M0DESIGNSTART
`else
$display("ERROR (tb_cmsdk_mcu.v) in CPU preprocessing directive : None of CORTEX_M0DESIGNSTART, CORTEX_M0 and CORTEX_M0PLUS are set. Please select one.");
$stop;
`endif
`endif
`endif
end
endmodule
This page: |
Created: | Wed Feb 22 13:33:08 2023 |
|
From: |
../verilog/tb_nanosoc.v |