Skip to content
Snippets Groups Projects
Commit 4674470e authored by dwf1m12's avatar dwf1m12
Browse files

debug and update APB tests and RTL to validate in nanosoc

parent 7cba872f
No related branches found
No related tags found
No related merge requests found
...@@ -129,7 +129,7 @@ int main (void) ...@@ -129,7 +129,7 @@ int main (void)
puts ("13: APB expansion port 13"); puts ("13: APB expansion port 13");
if ( ID_Check(&blank_id[0], 0x4000D000 ) == 1 ) err_code |= 1<<13; if ( ID_Check(&blank_id[0], 0x4000D000 ) == 1 ) err_code |= 1<<13;
puts ("14: APB expansion port 14"); puts ("14: APB expansion port 14");
if ( ID_Check(&blank_id[0], 0x4000E000 ) == 1 ) err_code |= 1<<14; if ( ID_Check(&apb_uart_id[0], CMSDK_USRT2_BASE ) == 1 ) err_code |= 1<<14;
puts ("15: APB expansion port 15 (optional DMA controller)"); puts ("15: APB expansion port 15 (optional DMA controller)");
if ( ID_Check(&pl230_udma_id[0], CMSDK_PL230_BASE ) == 1 ) err_code |= 1<<15; if ( ID_Check(&pl230_udma_id[0], CMSDK_PL230_BASE ) == 1 ) err_code |= 1<<15;
......
...@@ -108,7 +108,7 @@ ARM_CC_OPTIONS = -c -O3 -g -Otime -I $(DEVICE_DIR)/Include -I $(CORE_DIR) \ ...@@ -108,7 +108,7 @@ ARM_CC_OPTIONS = -c -O3 -g -Otime -I $(DEVICE_DIR)/Include -I $(CORE_DIR) \
-I $(SOFTWARE_DIR)/common/retarget $(USER_DEFINE) -I $(SOFTWARE_DIR)/common/retarget $(USER_DEFINE)
ARM_ASM_OPTIONS = -g ARM_ASM_OPTIONS = -g
ARM_LINK_OPTIONS = "--keep=$(STARTUP_FILE).o(RESET)" "--first=$(STARTUP_FILE).o(RESET)" \ ARM_LINK_OPTIONS = "--keep=$(STARTUP_FILE).o(RESET)" "--first=$(STARTUP_FILE).o(RESET)" \
--rw_base 0x20000000 --ro_base 0x00000000 --map --rw_base 0x30000000 --ro_base 0x00000000 --map
ifeq ($(COMPILE_BIGEND),1) ifeq ($(COMPILE_BIGEND),1)
# Big Endian # Big Endian
......
//-----------------------------------------------------------------------------
// 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-2011 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 : APB sub system
//-----------------------------------------------------------------------------
module cmsdk_apb_subsystem #(
// Enable setting for APB extension ports
// By default, all four extension ports are not used.
// This can be overriden by parameters at instantiations.
parameter APB_EXT_PORT12_ENABLE=0,
parameter APB_EXT_PORT13_ENABLE=0,
parameter APB_EXT_PORT14_ENABLE=0,
parameter APB_EXT_PORT15_ENABLE=0,
// If peripherals are generated with asynchronous clock domain to HCLK of the processor
// You might need to add synchroniser to the IRQ signal.
// In this example APB subsystem, the IRQ synchroniser is used to all peripherals
// when the INCLUDE_IRQ_SYNCHRONIZER parameter is set to 1. In practice you may have
// some IRQ signals need to be synchronised and some do not.
parameter INCLUDE_IRQ_SYNCHRONIZER=0,
// By default the APB subsystem include a simple test slave use in ARM for
// validation purpose. You can remove this test slave by setting the
// INCLUDE_APB_TEST_SLAVE paramater to 0,
parameter INCLUDE_APB_TEST_SLAVE = 1,
// Parameter options for including peripherals
parameter INCLUDE_APB_TIMER0 = 1, // Include simple timer #0
parameter INCLUDE_APB_TIMER1 = 1, // Include simple timer #1
parameter INCLUDE_APB_DUALTIMER0 = 1, // Include dual timer module
parameter INCLUDE_APB_UART0 = 1, // Include simple UART #0
parameter INCLUDE_APB_UART1 = 1, // Include simple UART #1
parameter INCLUDE_APB_UART2 = 1, // Include simple UART #2.
// Note : UART #2 is required for text messages
// display and to enable debug tester in
// debug tests
parameter INCLUDE_APB_WATCHDOG = 1, // Include APB watchdog module
// Big endian - Add additional endian conversion logic to support big endian.
// (for ARM internal testing and evaluation of the processor in
// big endian configuration).
// 0 = little endian, 1 = big endian
//
// The example systems including this APB subsystem are designed as
// little endian. Most of the peripherals and memory system are
// little endian. This parameter is introduced to allows ARM to
// perform system level tests to verified behaviour of bus
// components in big endian configuration, and to allow designers
// to evaluate the processor in big endian configuration.
//
// Use of this parameter is not recommended for actual product
// development as this adds extra hardware. For big endian systems
// ideally the peripherals should be modified to use a big endian
// programmer's model.
parameter BE = 0)
(
// --------------------------------------------------------------------------
// Port Definitions
// --------------------------------------------------------------------------
// AHB interface for AHB to APB bridge
input wire HCLK,
input wire HRESETn,
input wire HSEL,
input wire [15:0] HADDR,
input wire [1:0] HTRANS,
input wire HWRITE,
input wire [2:0] HSIZE,
input wire [3:0] HPROT,
input wire HREADY,
input wire [31:0] HWDATA,
output wire HREADYOUT,
output wire [31:0] HRDATA,
output wire HRESP,
input wire PCLK, // Peripheral clock
input wire PCLKG, // Gate PCLK for bus interface only
input wire PCLKEN, // Clock divider for AHB to APB bridge
input wire PRESETn, // APB reset
output wire [11:0] PADDR,
output wire PWRITE,
output wire [31:0] PWDATA,
output wire PENABLE,
output wire ext12_psel,
output wire ext13_psel,
output wire ext14_psel,
output wire ext15_psel,
input wire [31:0] ext12_prdata,
input wire ext12_pready,
input wire ext12_pslverr,
input wire [31:0] ext13_prdata,
input wire ext13_pready,
input wire ext13_pslverr,
input wire [31:0] ext14_prdata,
input wire ext14_pready,
input wire ext14_pslverr,
input wire [31:0] ext15_prdata,
input wire ext15_pready,
input wire ext15_pslverr,
output wire APBACTIVE,
// Peripherals
// UART
input wire uart0_rxd,
output wire uart0_txd,
output wire uart0_txen,
input wire uart1_rxd,
output wire uart1_txd,
output wire uart1_txen,
input wire uart2_rxd,
output wire uart2_txd,
output wire uart2_txen,
// Timer
input wire timer0_extin,
input wire timer1_extin,
// Interrupt outputs
output wire [31:0] apbsubsys_interrupt,
output wire watchdog_interrupt,
output wire watchdog_reset);
// --------------------------------------------------------------------------
// Internal wires
// --------------------------------------------------------------------------
wire [15:0] i_paddr;
wire i_psel;
wire i_penable;
wire i_pwrite;
wire [2:0] i_pprot;
wire [3:0] i_pstrb;
wire [31:0] i_pwdata;
// wire from APB slave mux to APB bridge
wire i_pready_mux;
wire [31:0] i_prdata_mux;
wire i_pslverr_mux;
// Peripheral signals
wire timer0_psel;
wire [31:0] timer0_prdata;
wire timer0_pready;
wire timer0_pslverr;
wire timer1_psel;
wire [31:0] timer1_prdata;
wire timer1_pready;
wire timer1_pslverr;
wire dualtimer2_psel;
wire [31:0] dualtimer2_prdata;
wire dualtimer2_pready;
wire dualtimer2_pslverr;
wire watchdog_psel;
wire [31:0] watchdog_prdata;
wire watchdog_pready;
wire watchdog_pslverr;
wire uart0_psel;
wire [31:0] uart0_prdata;
wire uart0_pready;
wire uart0_pslverr;
wire uart1_psel;
wire [31:0] uart1_prdata;
wire uart1_pready;
wire uart1_pslverr;
wire uart2_psel;
wire [31:0] uart2_prdata;
wire uart2_pready;
wire uart2_pslverr;
wire test_slave_psel;
wire [31:0] test_slave_prdata;
wire test_slave_pready;
wire test_slave_pslverr;
wire psel3;
wire psel7;
wire psel9;
wire psel10;
// Interrupt signals from peripherals
wire timer0_int;
wire timer1_int;
wire dualtimer2a_int;
wire dualtimer2b_int;
wire dualtimer2_comb_int;
wire uart0_txint;
wire uart0_rxint;
wire uart0_txovrint;
wire uart0_rxovrint;
wire uart0_combined_int;
wire uart1_txint;
wire uart1_rxint;
wire uart1_txovrint;
wire uart1_rxovrint;
wire uart1_combined_int;
wire uart2_txint;
wire uart2_rxint;
wire uart2_txovrint;
wire uart2_rxovrint;
wire uart2_combined_int;
wire uart0_overflow_int;
wire uart1_overflow_int;
wire uart2_overflow_int;
wire watchdog_int;
wire watchdog_rst;
// Synchronized interrupt signals
wire i_uart0_txint;
wire i_uart0_rxint;
wire i_uart0_overflow_int;
wire i_uart1_txint;
wire i_uart1_rxint;
wire i_uart1_overflow_int;
wire i_uart2_txint;
wire i_uart2_rxint;
wire i_uart2_overflow_int;
wire i_timer0_int;
wire i_timer1_int;
wire i_dualtimer2_int;
wire i_watchdog_int;
wire i_watchdog_rst;
// endian handling
wire bigendian;
assign bigendian = (BE!=0) ? 1'b1 : 1'b0;
wire [31:0] hwdata_le; // Little endian write data
wire [31:0] hrdata_le; // Little endian read data
wire reg_be_swap_ctrl_en = HSEL & HTRANS[1] & HREADY & bigendian;
reg [1:0] reg_be_swap_ctrl; // registered byte swap control
wire [1:0] nxt_be_swap_ctrl; // next state of byte swap control
assign nxt_be_swap_ctrl[1] = bigendian & (HSIZE[1:0]==2'b10); // Swap upper and lower half word
assign nxt_be_swap_ctrl[0] = bigendian & (HSIZE[1:0]!=2'b00); // Swap byte within hafword
// Register byte swap control for data phase
always @(posedge HCLK or negedge HRESETn)
begin
if (~HRESETn)
reg_be_swap_ctrl <= 2'b00;
else if (reg_be_swap_ctrl_en)
reg_be_swap_ctrl <= nxt_be_swap_ctrl;
end
// swap byte within half word
wire [31:0] hwdata_mux_1 = (reg_be_swap_ctrl[0] & bigendian) ?
{HWDATA[23:16],HWDATA[31:24],HWDATA[7:0],HWDATA[15:8]}:
{HWDATA[31:24],HWDATA[23:16],HWDATA[15:8],HWDATA[7:0]};
// swap lower and upper half word
assign hwdata_le = (reg_be_swap_ctrl[1] & bigendian) ?
{hwdata_mux_1[15: 0],hwdata_mux_1[31:16]}:
{hwdata_mux_1[31:16],hwdata_mux_1[15:0]};
// swap byte within half word
wire [31:0] hrdata_mux_1 = (reg_be_swap_ctrl[0] & bigendian) ?
{hrdata_le[23:16],hrdata_le[31:24],hrdata_le[ 7:0],hrdata_le[15:8]}:
{hrdata_le[31:24],hrdata_le[23:16],hrdata_le[15:8],hrdata_le[7:0]};
// swap lower and upper half word
assign HRDATA = (reg_be_swap_ctrl[1] & bigendian) ?
{hrdata_mux_1[15: 0],hrdata_mux_1[31:16]}:
{hrdata_mux_1[31:16],hrdata_mux_1[15:0]};
// AHB to APB bus bridge
cmsdk_ahb_to_apb
#(.ADDRWIDTH (16),
.REGISTER_RDATA (1),
.REGISTER_WDATA (0))
u_ahb_to_apb(
// AHB side
.HCLK (HCLK),
.HRESETn (HRESETn),
.HSEL (HSEL),
.HADDR (HADDR[15:0]),
.HTRANS (HTRANS),
.HSIZE (HSIZE),
.HPROT (HPROT),
.HWRITE (HWRITE),
.HREADY (HREADY),
.HWDATA (hwdata_le),
.HREADYOUT(HREADYOUT), // AHB Outputs
.HRDATA (hrdata_le),
.HRESP (HRESP),
.PADDR (i_paddr[15:0]),
.PSEL (i_psel),
.PENABLE (i_penable),
.PSTRB (i_pstrb),
.PPROT (i_pprot),
.PWRITE (i_pwrite),
.PWDATA (i_pwdata),
.APBACTIVE(APBACTIVE),
.PCLKEN (PCLKEN), // APB clock enable signal
.PRDATA (i_prdata_mux),
.PREADY (i_pready_mux),
.PSLVERR (i_pslverr_mux)
);
// APB slave multiplexer
cmsdk_apb_slave_mux
#( // Parameter to determine which ports are used
.PORT0_ENABLE (INCLUDE_APB_TIMER0), // timer 0
.PORT1_ENABLE (INCLUDE_APB_TIMER1), // timer 1
.PORT2_ENABLE (INCLUDE_APB_DUALTIMER0), // dual timer 0
.PORT3_ENABLE (1), // not used
.PORT4_ENABLE (INCLUDE_APB_UART0), // uart 0
.PORT5_ENABLE (INCLUDE_APB_UART1), // uart 1
.PORT6_ENABLE (INCLUDE_APB_UART2), // uart 2
.PORT7_ENABLE (1), // not used
.PORT8_ENABLE (INCLUDE_APB_WATCHDOG), // watchdog
.PORT9_ENABLE (1), // not used
.PORT10_ENABLE (1), // not used
.PORT11_ENABLE (INCLUDE_APB_TEST_SLAVE), // test slave for validation purpose
.PORT12_ENABLE (APB_EXT_PORT12_ENABLE),
.PORT13_ENABLE (APB_EXT_PORT13_ENABLE),
.PORT14_ENABLE (APB_EXT_PORT14_ENABLE),
.PORT15_ENABLE (APB_EXT_PORT15_ENABLE)
)
u_apb_slave_mux (
// Inputs
.DECODE4BIT (i_paddr[15:12]),
.PSEL (i_psel),
// PSEL (output) and return status & data (inputs) for each port
.PSEL0 (timer0_psel),
.PREADY0 (timer0_pready),
.PRDATA0 (timer0_prdata),
.PSLVERR0 (timer0_pslverr),
.PSEL1 (timer1_psel),
.PREADY1 (timer1_pready),
.PRDATA1 (timer1_prdata),
.PSLVERR1 (timer1_pslverr),
.PSEL2 (dualtimer2_psel),
.PREADY2 (dualtimer2_pready),
.PRDATA2 (dualtimer2_prdata),
.PSLVERR2 (dualtimer2_pslverr),
.PSEL3 (psel3),
.PREADY3 (1'b1),
.PRDATA3 (32'h00000000),
.PSLVERR3 (1'b0),
.PSEL4 (uart0_psel),
.PREADY4 (uart0_pready),
.PRDATA4 (uart0_prdata),
.PSLVERR4 (uart0_pslverr),
.PSEL5 (uart1_psel),
.PREADY5 (uart1_pready),
.PRDATA5 (uart1_prdata),
.PSLVERR5 (uart1_pslverr),
.PSEL6 (uart2_psel),
.PREADY6 (uart2_pready),
.PRDATA6 (uart2_prdata),
.PSLVERR6 (uart2_pslverr),
.PSEL7 (psel7),
.PREADY7 (1'b1),
.PRDATA7 (32'h00000000),
.PSLVERR7 (1'b0),
.PSEL8 (watchdog_psel),
.PREADY8 (watchdog_pready),
.PRDATA8 (watchdog_prdata),
.PSLVERR8 (watchdog_pslverr),
.PSEL9 (psel9),
.PREADY9 (1'b1),
.PRDATA9 (32'h00000000),
.PSLVERR9 (1'b0),
.PSEL10 (psel10),
.PREADY10 (1'b1),
.PRDATA10 (32'h00000000),
.PSLVERR10 (1'b0),
.PSEL11 (test_slave_psel),
.PREADY11 (test_slave_pready),
.PRDATA11 (test_slave_prdata),
.PSLVERR11 (test_slave_pslverr),
.PSEL12 (ext12_psel),
.PREADY12 (ext12_pready),
.PRDATA12 (ext12_prdata),
.PSLVERR12 (ext12_pslverr),
.PSEL13 (ext13_psel),
.PREADY13 (ext13_pready),
.PRDATA13 (ext13_prdata),
.PSLVERR13 (ext13_pslverr),
.PSEL14 (ext14_psel),
.PREADY14 (ext14_pready),
.PRDATA14 (ext14_prdata),
.PSLVERR14 (ext14_pslverr),
.PSEL15 (ext15_psel),
.PREADY15 (ext15_pready),
.PRDATA15 (ext15_prdata),
.PSLVERR15 (ext15_pslverr),
// Output
.PREADY (i_pready_mux),
.PRDATA (i_prdata_mux),
.PSLVERR (i_pslverr_mux)
);
// -----------------------------------------------------------------
// Timers
generate if (INCLUDE_APB_TIMER0 == 1) begin : gen_apb_timer_0
cmsdk_apb_timer u_apb_timer_0 (
.PCLK (PCLK), // PCLK for timer operation
.PCLKG (PCLKG), // Gated PCLK for bus
.PRESETn (PRESETn), // Reset
// APB interface inputs
.PSEL (timer0_psel),
.PADDR (i_paddr[11:2]),
.PENABLE (i_penable),
.PWRITE (i_pwrite),
.PWDATA (i_pwdata),
.ECOREVNUM (4'h0),// Engineering-change-order revision bits
// APB interface outputs
.PRDATA (timer0_prdata),
.PREADY (timer0_pready),
.PSLVERR (timer0_pslverr),
.EXTIN (timer0_extin), // Extenal input
.TIMERINT (timer0_int) // interrupt output
);
end else
begin : gen_no_apb_timer_0
assign timer0_prdata = {32{1'b0}};
assign timer0_pready = 1'b1;
assign timer0_pslverr = 1'b0;
assign timer0_int = 1'b0;
end endgenerate
generate if (INCLUDE_APB_TIMER1 == 1) begin : gen_apb_timer_1
cmsdk_apb_timer u_apb_timer_1 (
.PCLK (PCLK), // PCLK for timer operation
.PCLKG (PCLKG), // Gated PCLK for bus
.PRESETn (PRESETn), // Reset
// APB interface inputs
.PSEL (timer1_psel),
.PADDR (i_paddr[11:2]),
.PENABLE (i_penable),
.PWRITE (i_pwrite),
.PWDATA (i_pwdata),
.ECOREVNUM (4'h0),// Engineering-change-order revision bits
// APB interface outputs
.PRDATA (timer1_prdata),
.PREADY (timer1_pready),
.PSLVERR (timer1_pslverr),
.EXTIN (timer1_extin), // Extenal input
.TIMERINT (timer1_int) // interrupt output
);
end else
begin : gen_no_apb_timer_1
assign timer1_prdata = {32{1'b0}};
assign timer1_pready = 1'b1;
assign timer1_pslverr = 1'b0;
assign timer1_int = 1'b0;
end endgenerate
// -----------------------------------------------------------------
// Dual Timers
generate if (INCLUDE_APB_DUALTIMER0 == 1) begin : gen_apb_dualtimers_2
cmsdk_apb_dualtimers u_apb_dualtimers_2 (
// Inputs
.PCLK (PCLKG),
.PRESETn (PRESETn),
.PENABLE (i_penable),
.PSEL (dualtimer2_psel),
.PADDR (i_paddr[11:2]),
.PWRITE (i_pwrite),
.PWDATA (i_pwdata),
.TIMCLK (PCLK),
.TIMCLKEN1 (1'b1), // simple case:the timer 0 clock always enable
.TIMCLKEN2 (1'b1), // simple case:the timer 1 clock always enable
.ECOREVNUM (4'h0),// Engineering-change-order revision bits
// Outputs
.PRDATA (dualtimer2_prdata),
.TIMINT1 (dualtimer2a_int), // not used
.TIMINT2 (dualtimer2b_int), // not used
.TIMINTC (dualtimer2_comb_int)
);
end else
begin : gen_no_apb_dualtimers_2
assign dualtimer2_prdata = {32{1'b0}};
assign dualtimer2_comb_int = 1'b0;
assign dualtimer2a_int = 1'b0;
assign dualtimer2b_int = 1'b0;
end endgenerate
// When using peripherals with APB (AMBA 2.0), the PREADY and PSLVERR
// signals are not required. So we connect PREADY to 1 and PSLVERR to 0.
assign dualtimer2_pslverr = 1'b0;
assign dualtimer2_pready = 1'b1;
// -----------------------------------------------------------------
// Watchdog
generate if (INCLUDE_APB_WATCHDOG == 1) begin : gen_apb_watchdog
cmsdk_apb_watchdog u_apb_watchdog (
// Inputs
.PCLK (PCLKG),
.PRESETn (PRESETn),
.PENABLE (i_penable),
.PSEL (watchdog_psel),
.PADDR (i_paddr[11:2]),
.PWRITE (i_pwrite),
.PWDATA (i_pwdata),
.WDOGCLK (PCLK),
.WDOGCLKEN (1'b1),
.WDOGRESn (PRESETn),
.ECOREVNUM (4'h0),// Engineering-change-order revision bits
// Outputs
.PRDATA (watchdog_prdata),
.WDOGINT (watchdog_int), // connect to NMI
.WDOGRES (watchdog_rst) // connect to reset generator
);
end else
begin : gen_no_apb_watchdog
assign watchdog_prdata = {32{1'b0}};
assign watchdog_int = 1'b0;
assign watchdog_rst = 1'b0;
end endgenerate
// When using peripherals with APB (AMBA 2.0), the PREADY and PSLVERR
// signals are not required. So we connect PREADY to 1 and PSLVERR to 0.
assign watchdog_pslverr = 1'b0;
assign watchdog_pready = 1'b1;
// -----------------------------------------------------------------
// UARTs
generate if (INCLUDE_APB_UART0 == 1) begin : gen_apb_uart_0
cmsdk_apb_uart u_apb_uart_0 (
.PCLK (PCLK), // Peripheral clock
.PCLKG (PCLKG), // Gated PCLK for bus
.PRESETn (PRESETn), // Reset
.PSEL (uart0_psel), // APB interface inputs
.PADDR (i_paddr[11:2]),
.PENABLE (i_penable),
.PWRITE (i_pwrite),
.PWDATA (i_pwdata),
.PRDATA (uart0_prdata), // APB interface outputs
.PREADY (uart0_pready),
.PSLVERR (uart0_pslverr),
.ECOREVNUM (4'h0),// Engineering-change-order revision bits
.RXD (uart0_rxd), // Receive data
.TXD (uart0_txd), // Transmit data
.TXEN (uart0_txen), // Transmit Enabled
.BAUDTICK (), // Baud rate x16 tick output (for testing)
.TXINT (uart0_txint), // Transmit Interrupt
.RXINT (uart0_rxint), // Receive Interrupt
.TXOVRINT (uart0_txovrint), // Transmit Overrun Interrupt
.RXOVRINT (uart0_rxovrint), // Receive Overrun Interrupt
.UARTINT (uart0_combined_int) // Combined Interrupt
);
end else
begin : gen_no_apb_uart_0
assign uart0_prdata = {32{1'b0}};
assign uart0_pready = 1'b1;
assign uart0_pslverr = 1'b0;
assign uart0_txd = 1'b1;
assign uart0_txen = 1'b0;
assign uart0_txint = 1'b0;
assign uart0_rxint = 1'b0;
assign uart0_txovrint = 1'b0;
assign uart0_rxovrint = 1'b0;
assign uart0_combined_int = 1'b0;
end endgenerate
generate if (INCLUDE_APB_UART1 == 1) begin : gen_apb_uart_1
cmsdk_apb_uart u_apb_uart_1 (
.PCLK (PCLK), // Peripheral clock
.PCLKG (PCLKG), // Gated PCLK for bus
.PRESETn (PRESETn), // Reset
.PSEL (uart1_psel), // APB interface inputs
.PADDR (i_paddr[11:2]),
.PENABLE (i_penable),
.PWRITE (i_pwrite),
.PWDATA (i_pwdata),
.PRDATA (uart1_prdata), // APB interface outputs
.PREADY (uart1_pready),
.PSLVERR (uart1_pslverr),
.ECOREVNUM (4'h0),// Engineering-change-order revision bits
.RXD (uart1_rxd), // Receive data
.TXD (uart1_txd), // Transmit data
.TXEN (uart1_txen), // Transmit Enabled
.BAUDTICK (), // Baud rate x16 tick output (for testing)
.TXINT (uart1_txint), // Transmit Interrupt
.RXINT (uart1_rxint), // Receive Interrupt
.TXOVRINT (uart1_txovrint), // Transmit Overrun Interrupt
.RXOVRINT (uart1_rxovrint), // Receive Overrun Interrupt
.UARTINT (uart1_combined_int) // Combined Interrupt
);
end else
begin : gen_no_apb_uart_1
assign uart1_prdata = {32{1'b0}};
assign uart1_pready = 1'b1;
assign uart1_pslverr = 1'b0;
assign uart1_txd = 1'b1;
assign uart1_txen = 1'b0;
assign uart1_txint = 1'b0;
assign uart1_rxint = 1'b0;
assign uart1_txovrint = 1'b0;
assign uart1_rxovrint = 1'b0;
assign uart1_combined_int = 1'b0;
end endgenerate
generate if (INCLUDE_APB_UART2 == 1) begin : gen_apb_uart_2
cmsdk_apb_uart u_apb_uart_2 (
.PCLK (PCLK), // Peripheral clock
.PCLKG (PCLKG), // Gated PCLK for bus
.PRESETn (PRESETn), // Reset
.PSEL (uart2_psel), // APB interface inputs
.PADDR (i_paddr[11:2]),
.PENABLE (i_penable),
.PWRITE (i_pwrite),
.PWDATA (i_pwdata),
.PRDATA (uart2_prdata), // APB interface outputs
.PREADY (uart2_pready),
.PSLVERR (uart2_pslverr),
.ECOREVNUM (4'h0),// Engineering-change-order revision bits
.RXD (uart2_rxd), // Receive data
.TXD (uart2_txd), // Transmit data
.TXEN (uart2_txen), // Transmit Enabled
.BAUDTICK (), // Baud rate x16 tick output (for testing)
.TXINT (uart2_txint), // Transmit Interrupt
.RXINT (uart2_rxint), // Receive Interrupt
.TXOVRINT (uart2_txovrint), // Transmit Overrun Interrupt
.RXOVRINT (uart2_rxovrint), // Receive Overrun Interrupt
.UARTINT (uart2_combined_int) // Combined Interrupt
);
end else
begin : gen_no_apb_uart_2
assign uart2_prdata = {32{1'b0}};
assign uart2_pready = 1'b1;
assign uart2_pslverr = 1'b0;
assign uart2_txd = 1'b1;
assign uart2_txen = 1'b0;
assign uart2_txint = 1'b0;
assign uart2_rxint = 1'b0;
assign uart2_txovrint = 1'b0;
assign uart2_rxovrint = 1'b0;
assign uart2_combined_int = 1'b0;
end endgenerate
// -----------------------------------------------------------------
// Test slave (for validation purpose)
generate if (INCLUDE_APB_TEST_SLAVE == 1) begin : gen_apb_test_slave
cmsdk_apb_test_slave u_apb_test_slave(
.PCLK (PCLKG), // use Gated PCLK for bus
.PRESETn (PRESETn), // Reset
.PSEL (test_slave_psel), // APB interface inputs
.PADDR (i_paddr[11:2]),
.PENABLE (i_penable),
.PSTRB (i_pstrb[3:0]),
.PWRITE (i_pwrite),
.PWDATA (i_pwdata),
.PRDATA (test_slave_prdata), // APB interface outputs
.PREADY (test_slave_pready),
.PSLVERR (test_slave_pslverr)
);
end else
begin : gen_no_apb_test_slave
assign test_slave_prdata = {32{1'b0}};
assign test_slave_pready = 1'b1;
assign test_slave_pslverr = 1'b0;
end endgenerate
// -----------------------------------------------------------------
// Connection to external
assign PADDR = i_paddr[11:0];
assign PENABLE = i_penable;
assign PWRITE = i_pwrite;
assign PWDATA = i_pwdata;
assign uart0_overflow_int = uart0_txovrint|uart0_rxovrint;
assign uart1_overflow_int = uart1_txovrint|uart1_rxovrint;
assign uart2_overflow_int = uart2_txovrint|uart2_rxovrint;
generate if (INCLUDE_IRQ_SYNCHRONIZER == 0) begin : gen_irq_synchroniser
// If PCLK is syncrhonous to HCLK, no need to have synchronizers
assign i_uart0_txint = uart0_txint;
assign i_uart0_rxint = uart0_rxint;
assign i_uart1_txint = uart1_txint;
assign i_uart1_rxint = uart1_rxint;
assign i_uart2_txint = uart2_txint;
assign i_uart2_rxint = uart2_rxint;
assign i_timer0_int = timer0_int;
assign i_timer1_int = timer1_int;
assign i_dualtimer2_int = dualtimer2_comb_int;
assign i_uart0_overflow_int = uart0_overflow_int;
assign i_uart1_overflow_int = uart1_overflow_int;
assign i_uart2_overflow_int = uart2_overflow_int;
assign i_watchdog_int = watchdog_int;
assign i_watchdog_rst = watchdog_rst;
end else
begin : gen_no_irq_synchroniser
// If IRQ source are asyncrhonous to HCLK, then we
// need to add synchronizers to prevent metastability
// on interrupt signals.
cmsdk_irq_sync u_irq_sync_0 (
.RSTn (HRESETn),
.CLK (HCLK),
.IRQIN (uart0_txint),
.IRQOUT(i_uart0_txint)
);
cmsdk_irq_sync u_irq_sync_1 (
.RSTn (HRESETn),
.CLK (HCLK),
.IRQIN (uart0_rxint),
.IRQOUT(i_uart0_rxint)
);
cmsdk_irq_sync u_irq_sync_2 (
.RSTn (HRESETn),
.CLK (HCLK),
.IRQIN (uart1_txint),
.IRQOUT(i_uart1_txint)
);
cmsdk_irq_sync u_irq_sync_3 (
.RSTn (HRESETn),
.CLK (HCLK),
.IRQIN (uart1_rxint),
.IRQOUT(i_uart1_rxint)
);
cmsdk_irq_sync u_irq_sync_4 (
.RSTn (HRESETn),
.CLK (HCLK),
.IRQIN (uart2_txint),
.IRQOUT(i_uart2_txint)
);
cmsdk_irq_sync u_irq_sync_5 (
.RSTn (HRESETn),
.CLK (HCLK),
.IRQIN (uart2_rxint),
.IRQOUT(i_uart2_rxint)
);
cmsdk_irq_sync u_irq_sync_6 (
.RSTn (HRESETn),
.CLK (HCLK),
.IRQIN (timer0_int),
.IRQOUT(i_timer0_int)
);
cmsdk_irq_sync u_irq_sync_7 (
.RSTn (HRESETn),
.CLK (HCLK),
.IRQIN (timer1_int),
.IRQOUT(i_timer1_int)
);
cmsdk_irq_sync u_irq_sync_8 (
.RSTn (HRESETn),
.CLK (HCLK),
.IRQIN (dualtimer2_comb_int),
.IRQOUT(i_dualtimer2_int)
);
cmsdk_irq_sync u_irq_sync_9 (
.RSTn (HRESETn),
.CLK (HCLK),
.IRQIN (uart0_overflow_int),
.IRQOUT(i_uart0_overflow_int)
);
cmsdk_irq_sync u_irq_sync_10 (
.RSTn (HRESETn),
.CLK (HCLK),
.IRQIN (uart1_overflow_int),
.IRQOUT(i_uart1_overflow_int)
);
cmsdk_irq_sync u_irq_sync_11 (
.RSTn (HRESETn),
.CLK (HCLK),
.IRQIN (uart2_overflow_int),
.IRQOUT(i_uart2_overflow_int)
);
cmsdk_irq_sync u_irq_sync_12 (
.RSTn (HRESETn),
.CLK (HCLK),
.IRQIN (watchdog_int),
.IRQOUT(i_watchdog_int)
);
cmsdk_irq_sync u_irq_sync_13 (
.RSTn (HRESETn),
.CLK (HCLK),
.IRQIN (watchdog_rst),
.IRQOUT(i_watchdog_rst)
);
end endgenerate
assign apbsubsys_interrupt[31:0] = {
{16{1'b0}}, // 16-31 (AHB GPIO #0 individual interrupt)
1'b0, // 15 (DMA interrupt)
i_uart2_overflow_int, // 14
i_uart1_overflow_int, // 13
i_uart0_overflow_int, // 12
1'b0, // 11
i_dualtimer2_int, // 10
i_timer1_int, // 9
i_timer0_int, // 8
1'b0, // 7 (GPIO #1 combined interrupt)
1'b0, // 6 (GPIO #0 combined interrupt)
i_uart2_txint, // 5
i_uart2_rxint, // 4
i_uart1_txint, // 3
i_uart1_rxint, // 2
i_uart0_txint, // 1
i_uart0_rxint}; // 0
assign watchdog_interrupt = i_watchdog_int;
assign watchdog_reset = i_watchdog_rst;
`ifdef ARM_APB_ASSERT_ON
// ------------------------------------------------------------
// Assertions
// ------------------------------------------------------------
`include "std_ovl_defines.h"
// PSEL should be one-hot
// If this OVL fires - there is an error in the design of the address decoder
assert_zero_one_hot
#(`OVL_FATAL,16,`OVL_ASSERT,
"Only one PSEL input can be activated.")
u_ovl_psel_one_hot
(.clk(PCLK), .reset_n(PRESETn),
.test_expr({timer0_psel,timer1_psel,dualtimer2_psel,uart0_psel,uart1_psel,uart2_psel,watchdog_psel,
test_slave_psel,ext12_psel,ext13_psel,ext14_psel,ext15_psel,psel3,psel7,psel9,psel10}));
// All Writes to the APB peripherals must be word size since PSTRB only
// supported on the APB test slave. Therefore, the AHB bridge can generate
// non-word sized writes which can break the APB peripherals (not
// including the the test slave) since they don't support this (i.e. PSTRB
// is not present). Hence, restrict the appropriate accesses to word sized
// writes.
assert_implication
#(`OVL_ERROR,`OVL_ASSERT,
"All Writes to the APB peripherals must be word size not including the test slave")
u_ovl_apb_write_word_size_32bits
(.clk (PCLK),
.reset_n (PRESETn),
.antecedent_expr (i_penable && i_psel && i_pwrite && (~test_slave_psel)),
.consequent_expr (i_pstrb == 4'b1111)
);
// This protocol checker is placed here and attached to the PCLK and PCLKEN.
// A note should be made that this means that the value of PCLKEN may not
// necessarily be the same as the enable term that is gating PCLK to generate
// PCLKG.
ApbPC #(.ADDR_WIDTH (16),
.DATA_WIDTH (32),
.SEL_WIDTH (1),
// OVL instances property_type (0=assert, 1=assume, 2=ignore)
.MASTER_REQUIREMENT_PROPTYPE (0),
.SLAVE_REQUIREMENT_PROPTYPE (0),
.PREADY_FUNCTIONAL (1),
.PSLVERR_FUNCTIONAL (1),
.PPROT_FUNCTIONAL (1),
.PSTRB_FUNCTIONAL (1)
) u_ApbPC
(
// Inputs
.PCLK (PCLK),
.PRESETn (PRESETn),
.PSELx (i_psel),
.PPROT (i_pprot),
.PSTRB (i_pstrb),
.PENABLE (i_penable),
.PREADY (i_pready_mux),
.PSLVERR (i_pslverr_mux),
.PADDR (i_paddr),
.PWRITE (i_pwrite),
.PWDATA (i_pwdata),
.PRDATA (i_prdata_mux)
);
`endif
endmodule
...@@ -1490,6 +1490,10 @@ localparam AWRAM9 = 14; // 16KB ...@@ -1490,6 +1490,10 @@ localparam AWRAM9 = 14; // 16KB
assign exp12_pready = 1'b1; assign exp12_pready = 1'b1;
assign exp13_pready = 1'b1; assign exp13_pready = 1'b1;
assign exp12_pslverr = 1'b0;
assign exp13_pslverr = 1'b0;
assign exp12_prdata = 32'h0;
assign exp13_prdata = 32'h0;
// Serial wire debug is used. nTRST, TDI and TDO are not needed // Serial wire debug is used. nTRST, TDI and TDO are not needed
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment