URL
https://opencores.org/ocsvn/openmsp430/openmsp430/trunk
Subversion Repositories openmsp430
Compare Revisions
- This comparison shows the changes necessary to convert path
/openmsp430/trunk/core/bench
- from Rev 200 to Rev 202
- ↔ Reverse comparison
Rev 200 → Rev 202
/verilog/tb_openMSP430.v
68,6 → 68,17
wire [1:0] per_we; |
wire per_en; |
|
// Direct Memory Access interface |
wire [15:0] dma_dout; |
wire dma_ready; |
wire dma_resp; |
reg [15:1] dma_addr; |
reg [15:0] dma_din; |
reg dma_en; |
reg dma_priority; |
reg [1:0] dma_we; |
reg dma_wkup; |
|
// Digital I/O |
wire irq_port1; |
wire irq_port2; |
192,6 → 203,7
|
// Testbench variables |
integer tb_idx; |
integer tmp_seed; |
integer error; |
reg stimulus_done; |
|
207,6 → 219,9
`include "dbg_uart_tasks.v" |
`include "dbg_i2c_tasks.v" |
|
// Direct Memory Access interface tasks |
`include "dma_tasks.v" |
|
// Verilog stimulus |
`include "stimulus.v" |
|
265,11 → 280,20
|
initial |
begin |
tmp_seed = `SEED; |
tmp_seed = $urandom(tmp_seed); |
error = 0; |
stimulus_done = 1; |
irq = {`IRQ_NR-2{1'b0}}; |
nmi = 1'b0; |
wkup = 14'h0000; |
dma_addr = 15'h0000; |
dma_din = 16'h0000; |
dma_en = 1'b0; |
dma_priority = 1'b0; |
dma_we = 2'b00; |
dma_wkup = 1'b0; |
dma_tfx_cancel = 1'b0; |
cpu_en = 1'b1; |
dbg_en = 1'b0; |
dbg_uart_rxd_sel = 1'b0; |
314,14 → 338,14
ram #(`PMEM_MSB, `PMEM_SIZE) pmem_0 ( |
|
// OUTPUTs |
.ram_dout (pmem_dout), // Program Memory data output |
.ram_dout (pmem_dout), // Program Memory data output |
|
// INPUTs |
.ram_addr (pmem_addr), // Program Memory address |
.ram_cen (pmem_cen), // Program Memory chip enable (low active) |
.ram_clk (mclk), // Program Memory clock |
.ram_din (pmem_din), // Program Memory data input |
.ram_wen (pmem_wen) // Program Memory write enable (low active) |
.ram_addr (pmem_addr), // Program Memory address |
.ram_cen (pmem_cen), // Program Memory chip enable (low active) |
.ram_clk (mclk), // Program Memory clock |
.ram_din (pmem_din), // Program Memory data input |
.ram_wen (pmem_wen) // Program Memory write enable (low active) |
); |
|
|
332,14 → 356,14
ram #(`DMEM_MSB, `DMEM_SIZE) dmem_0 ( |
|
// OUTPUTs |
.ram_dout (dmem_dout), // Data Memory data output |
.ram_dout (dmem_dout), // Data Memory data output |
|
// INPUTs |
.ram_addr (dmem_addr), // Data Memory address |
.ram_cen (dmem_cen), // Data Memory chip enable (low active) |
.ram_clk (mclk), // Data Memory clock |
.ram_din (dmem_din), // Data Memory data input |
.ram_wen (dmem_wen) // Data Memory write enable (low active) |
.ram_addr (dmem_addr), // Data Memory address |
.ram_cen (dmem_cen), // Data Memory chip enable (low active) |
.ram_clk (mclk), // Data Memory clock |
.ram_din (dmem_din), // Data Memory data input |
.ram_wen (dmem_wen) // Data Memory write enable (low active) |
); |
|
|
350,52 → 374,61
openMSP430 dut ( |
|
// OUTPUTs |
.aclk (aclk), // ASIC ONLY: ACLK |
.aclk_en (aclk_en), // FPGA ONLY: ACLK enable |
.dbg_freeze (dbg_freeze), // Freeze peripherals |
.dbg_i2c_sda_out (dbg_sda_slave_out), // Debug interface: I2C SDA OUT |
.dbg_uart_txd (dbg_uart_txd), // Debug interface: UART TXD |
.dco_enable (dco_enable), // ASIC ONLY: Fast oscillator enable |
.dco_wkup (dco_wkup), // ASIC ONLY: Fast oscillator wake-up (asynchronous) |
.dmem_addr (dmem_addr), // Data Memory address |
.dmem_cen (dmem_cen), // Data Memory chip enable (low active) |
.dmem_din (dmem_din), // Data Memory data input |
.dmem_wen (dmem_wen), // Data Memory write enable (low active) |
.irq_acc (irq_acc), // Interrupt request accepted (one-hot signal) |
.lfxt_enable (lfxt_enable), // ASIC ONLY: Low frequency oscillator enable |
.lfxt_wkup (lfxt_wkup), // ASIC ONLY: Low frequency oscillator wake-up (asynchronous) |
.mclk (mclk), // Main system clock |
.per_addr (per_addr), // Peripheral address |
.per_din (per_din), // Peripheral data input |
.per_we (per_we), // Peripheral write enable (high active) |
.per_en (per_en), // Peripheral enable (high active) |
.pmem_addr (pmem_addr), // Program Memory address |
.pmem_cen (pmem_cen), // Program Memory chip enable (low active) |
.pmem_din (pmem_din), // Program Memory data input (optional) |
.pmem_wen (pmem_wen), // Program Memory write enable (low active) (optional) |
.puc_rst (puc_rst), // Main system reset |
.smclk (smclk), // ASIC ONLY: SMCLK |
.smclk_en (smclk_en), // FPGA ONLY: SMCLK enable |
.aclk (aclk), // ASIC ONLY: ACLK |
.aclk_en (aclk_en), // FPGA ONLY: ACLK enable |
.dbg_freeze (dbg_freeze), // Freeze peripherals |
.dbg_i2c_sda_out (dbg_sda_slave_out), // Debug interface: I2C SDA OUT |
.dbg_uart_txd (dbg_uart_txd), // Debug interface: UART TXD |
.dco_enable (dco_enable), // ASIC ONLY: Fast oscillator enable |
.dco_wkup (dco_wkup), // ASIC ONLY: Fast oscillator wake-up (asynchronous) |
.dmem_addr (dmem_addr), // Data Memory address |
.dmem_cen (dmem_cen), // Data Memory chip enable (low active) |
.dmem_din (dmem_din), // Data Memory data input |
.dmem_wen (dmem_wen), // Data Memory write byte enable (low active) |
.irq_acc (irq_acc), // Interrupt request accepted (one-hot signal) |
.lfxt_enable (lfxt_enable), // ASIC ONLY: Low frequency oscillator enable |
.lfxt_wkup (lfxt_wkup), // ASIC ONLY: Low frequency oscillator wake-up (asynchronous) |
.mclk (mclk), // Main system clock |
.dma_dout (dma_dout), // Direct Memory Access data output |
.dma_ready (dma_ready), // Direct Memory Access is complete |
.dma_resp (dma_resp), // Direct Memory Access response (0:Okay / 1:Error) |
.per_addr (per_addr), // Peripheral address |
.per_din (per_din), // Peripheral data input |
.per_en (per_en), // Peripheral enable (high active) |
.per_we (per_we), // Peripheral write byte enable (high active) |
.pmem_addr (pmem_addr), // Program Memory address |
.pmem_cen (pmem_cen), // Program Memory chip enable (low active) |
.pmem_din (pmem_din), // Program Memory data input (optional) |
.pmem_wen (pmem_wen), // Program Memory write byte enable (low active) (optional) |
.puc_rst (puc_rst), // Main system reset |
.smclk (smclk), // ASIC ONLY: SMCLK |
.smclk_en (smclk_en), // FPGA ONLY: SMCLK enable |
|
// INPUTs |
.cpu_en (cpu_en), // Enable CPU code execution (asynchronous) |
.dbg_en (dbg_en), // Debug interface enable (asynchronous) |
.dbg_i2c_addr (I2C_ADDR), // Debug interface: I2C Address |
.dbg_i2c_broadcast (I2C_BROADCAST), // Debug interface: I2C Broadcast Address (for multicore systems) |
.dbg_i2c_scl (dbg_scl_slave), // Debug interface: I2C SCL |
.dbg_i2c_sda_in (dbg_sda_slave_in), // Debug interface: I2C SDA IN |
.dbg_uart_rxd (dbg_uart_rxd), // Debug interface: UART RXD (asynchronous) |
.dco_clk (dco_clk), // Fast oscillator (fast clock) |
.dmem_dout (dmem_dout), // Data Memory data output |
.irq (irq_in), // Maskable interrupts |
.lfxt_clk (lfxt_clk), // Low frequency oscillator (typ 32kHz) |
.nmi (nmi), // Non-maskable interrupt (asynchronous) |
.per_dout (per_dout), // Peripheral data output |
.pmem_dout (pmem_dout), // Program Memory data output |
.reset_n (reset_n), // Reset Pin (low active, asynchronous) |
.scan_enable (scan_enable), // ASIC ONLY: Scan enable (active during scan shifting) |
.scan_mode (scan_mode), // ASIC ONLY: Scan mode |
.wkup (|wkup_in) // ASIC ONLY: System Wake-up (asynchronous) |
.cpu_en (cpu_en), // Enable CPU code execution (asynchronous) |
.dbg_en (dbg_en), // Debug interface enable (asynchronous) |
.dbg_i2c_addr (I2C_ADDR), // Debug interface: I2C Address |
.dbg_i2c_broadcast (I2C_BROADCAST), // Debug interface: I2C Broadcast Address (for multicore systems) |
.dbg_i2c_scl (dbg_scl_slave), // Debug interface: I2C SCL |
.dbg_i2c_sda_in (dbg_sda_slave_in), // Debug interface: I2C SDA IN |
.dbg_uart_rxd (dbg_uart_rxd), // Debug interface: UART RXD (asynchronous) |
.dco_clk (dco_clk), // Fast oscillator (fast clock) |
.dmem_dout (dmem_dout), // Data Memory data output |
.irq (irq_in), // Maskable interrupts |
.lfxt_clk (lfxt_clk), // Low frequency oscillator (typ 32kHz) |
.dma_addr (dma_addr), // Direct Memory Access address |
.dma_din (dma_din), // Direct Memory Access data input |
.dma_en (dma_en), // Direct Memory Access enable (high active) |
.dma_priority (dma_priority), // Direct Memory Access priority (0:low / 1:high) |
.dma_we (dma_we), // Direct Memory Access write byte enable (high active) |
.dma_wkup (dma_wkup), // ASIC ONLY: DMA Sub-System Wake-up (asynchronous and non-glitchy) |
.nmi (nmi), // Non-maskable interrupt (asynchronous) |
.per_dout (per_dout), // Peripheral data output |
.pmem_dout (pmem_dout), // Program Memory data output |
.reset_n (reset_n), // Reset Pin (low active, asynchronous) |
.scan_enable (scan_enable), // ASIC ONLY: Scan enable (active during scan shifting) |
.scan_mode (scan_mode), // ASIC ONLY: Scan mode |
.wkup (|wkup_in) // ASIC ONLY: System Wake-up (asynchronous) |
); |
|
// |
419,41 → 452,41
`endif |
|
// OUTPUTs |
.irq_port1 (irq_port1), // Port 1 interrupt |
.irq_port2 (irq_port2), // Port 2 interrupt |
.p1_dout (p1_dout), // Port 1 data output |
.p1_dout_en (p1_dout_en), // Port 1 data output enable |
.p1_sel (p1_sel), // Port 1 function select |
.p2_dout (p2_dout), // Port 2 data output |
.p2_dout_en (p2_dout_en), // Port 2 data output enable |
.p2_sel (p2_sel), // Port 2 function select |
.p3_dout (p3_dout), // Port 3 data output |
.p3_dout_en (p3_dout_en), // Port 3 data output enable |
.p3_sel (p3_sel), // Port 3 function select |
.p4_dout (p4_dout), // Port 4 data output |
.p4_dout_en (p4_dout_en), // Port 4 data output enable |
.p4_sel (p4_sel), // Port 4 function select |
.p5_dout (p5_dout), // Port 5 data output |
.p5_dout_en (p5_dout_en), // Port 5 data output enable |
.p5_sel (p5_sel), // Port 5 function select |
.p6_dout (p6_dout), // Port 6 data output |
.p6_dout_en (p6_dout_en), // Port 6 data output enable |
.p6_sel (p6_sel), // Port 6 function select |
.per_dout (per_dout_dio), // Peripheral data output |
.irq_port1 (irq_port1), // Port 1 interrupt |
.irq_port2 (irq_port2), // Port 2 interrupt |
.p1_dout (p1_dout), // Port 1 data output |
.p1_dout_en (p1_dout_en), // Port 1 data output enable |
.p1_sel (p1_sel), // Port 1 function select |
.p2_dout (p2_dout), // Port 2 data output |
.p2_dout_en (p2_dout_en), // Port 2 data output enable |
.p2_sel (p2_sel), // Port 2 function select |
.p3_dout (p3_dout), // Port 3 data output |
.p3_dout_en (p3_dout_en), // Port 3 data output enable |
.p3_sel (p3_sel), // Port 3 function select |
.p4_dout (p4_dout), // Port 4 data output |
.p4_dout_en (p4_dout_en), // Port 4 data output enable |
.p4_sel (p4_sel), // Port 4 function select |
.p5_dout (p5_dout), // Port 5 data output |
.p5_dout_en (p5_dout_en), // Port 5 data output enable |
.p5_sel (p5_sel), // Port 5 function select |
.p6_dout (p6_dout), // Port 6 data output |
.p6_dout_en (p6_dout_en), // Port 6 data output enable |
.p6_sel (p6_sel), // Port 6 function select |
.per_dout (per_dout_dio), // Peripheral data output |
|
// INPUTs |
.mclk (mclk), // Main system clock |
.p1_din (p1_din), // Port 1 data input |
.p2_din (p2_din), // Port 2 data input |
.p3_din (p3_din), // Port 3 data input |
.p4_din (p4_din), // Port 4 data input |
.p5_din (p5_din), // Port 5 data input |
.p6_din (p6_din), // Port 6 data input |
.per_addr (per_addr), // Peripheral address |
.per_din (per_din), // Peripheral data input |
.per_en (per_en), // Peripheral enable (high active) |
.per_we (per_we), // Peripheral write enable (high active) |
.puc_rst (puc_rst) // Main system reset |
.mclk (mclk), // Main system clock |
.p1_din (p1_din), // Port 1 data input |
.p2_din (p2_din), // Port 2 data input |
.p3_din (p3_din), // Port 3 data input |
.p4_din (p4_din), // Port 4 data input |
.p5_din (p5_din), // Port 5 data input |
.p6_din (p6_din), // Port 6 data input |
.per_addr (per_addr), // Peripheral address |
.per_din (per_din), // Peripheral data input |
.per_en (per_en), // Peripheral enable (high active) |
.per_we (per_we), // Peripheral write enable (high active) |
.puc_rst (puc_rst) // Main system reset |
); |
|
// |
463,38 → 496,37
omsp_timerA timerA_0 ( |
|
// OUTPUTs |
.irq_ta0 (irq_ta0), // Timer A interrupt: TACCR0 |
.irq_ta1 (irq_ta1), // Timer A interrupt: TAIV, TACCR1, TACCR2 |
.per_dout (per_dout_timerA), // Peripheral data output |
.ta_out0 (ta_out0), // Timer A output 0 |
.ta_out0_en (ta_out0_en), // Timer A output 0 enable |
.ta_out1 (ta_out1), // Timer A output 1 |
.ta_out1_en (ta_out1_en), // Timer A output 1 enable |
.ta_out2 (ta_out2), // Timer A output 2 |
.ta_out2_en (ta_out2_en), // Timer A output 2 enable |
.irq_ta0 (irq_ta0), // Timer A interrupt: TACCR0 |
.irq_ta1 (irq_ta1), // Timer A interrupt: TAIV, TACCR1, TACCR2 |
.per_dout (per_dout_timerA), // Peripheral data output |
.ta_out0 (ta_out0), // Timer A output 0 |
.ta_out0_en (ta_out0_en), // Timer A output 0 enable |
.ta_out1 (ta_out1), // Timer A output 1 |
.ta_out1_en (ta_out1_en), // Timer A output 1 enable |
.ta_out2 (ta_out2), // Timer A output 2 |
.ta_out2_en (ta_out2_en), // Timer A output 2 enable |
|
// INPUTs |
.aclk_en (aclk_en), // ACLK enable (from CPU) |
.dbg_freeze (dbg_freeze), // Freeze Timer A counter |
.inclk (inclk), // INCLK external timer clock (SLOW) |
.irq_ta0_acc (irq_acc[`IRQ_NR-7]),// Interrupt request TACCR0 accepted |
.mclk (mclk), // Main system clock |
.per_addr (per_addr), // Peripheral address |
.per_din (per_din), // Peripheral data input |
.per_en (per_en), // Peripheral enable (high active) |
.per_we (per_we), // Peripheral write enable (high active) |
.puc_rst (puc_rst), // Main system reset |
.smclk_en (smclk_en), // SMCLK enable (from CPU) |
.ta_cci0a (ta_cci0a), // Timer A compare 0 input A |
.ta_cci0b (ta_cci0b), // Timer A compare 0 input B |
.ta_cci1a (ta_cci1a), // Timer A compare 1 input A |
.ta_cci1b (ta_cci1b), // Timer A compare 1 input B |
.ta_cci2a (ta_cci2a), // Timer A compare 2 input A |
.ta_cci2b (ta_cci2b), // Timer A compare 2 input B |
.taclk (taclk) // TACLK external timer clock (SLOW) |
.aclk_en (aclk_en), // ACLK enable (from CPU) |
.dbg_freeze (dbg_freeze), // Freeze Timer A counter |
.inclk (inclk), // INCLK external timer clock (SLOW) |
.irq_ta0_acc (irq_acc[`IRQ_NR-7]), // Interrupt request TACCR0 accepted |
.mclk (mclk), // Main system clock |
.per_addr (per_addr), // Peripheral address |
.per_din (per_din), // Peripheral data input |
.per_en (per_en), // Peripheral enable (high active) |
.per_we (per_we), // Peripheral write enable (high active) |
.puc_rst (puc_rst), // Main system reset |
.smclk_en (smclk_en), // SMCLK enable (from CPU) |
.ta_cci0a (ta_cci0a), // Timer A compare 0 input A |
.ta_cci0b (ta_cci0b), // Timer A compare 0 input B |
.ta_cci1a (ta_cci1a), // Timer A compare 1 input A |
.ta_cci1b (ta_cci1b), // Timer A compare 1 input B |
.ta_cci2a (ta_cci2a), // Timer A compare 2 input A |
.ta_cci2b (ta_cci2b), // Timer A compare 2 input B |
.taclk (taclk) // TACLK external timer clock (SLOW) |
); |
|
|
// |
// Peripheral templates |
//---------------------------------- |
502,32 → 534,32
template_periph_8b template_periph_8b_0 ( |
|
// OUTPUTs |
.per_dout (per_dout_temp_8b), // Peripheral data output |
.per_dout (per_dout_temp_8b), // Peripheral data output |
|
// INPUTs |
.mclk (mclk), // Main system clock |
.per_addr (per_addr), // Peripheral address |
.per_din (per_din), // Peripheral data input |
.per_en (per_en), // Peripheral enable (high active) |
.per_we (per_we), // Peripheral write enable (high active) |
.puc_rst (puc_rst) // Main system reset |
.mclk (mclk), // Main system clock |
.per_addr (per_addr), // Peripheral address |
.per_din (per_din), // Peripheral data input |
.per_en (per_en), // Peripheral enable (high active) |
.per_we (per_we), // Peripheral write enable (high active) |
.puc_rst (puc_rst) // Main system reset |
); |
|
`ifdef CVER |
template_periph_16b #(15'h0190) template_periph_16b_0 ( |
template_periph_16b #(15'h0190) template_periph_16b_0 ( |
`else |
template_periph_16b #(.BASE_ADDR((15'd`PER_SIZE-15'h0070) & 15'h7ff8)) template_periph_16b_0 ( |
`endif |
// OUTPUTs |
.per_dout (per_dout_temp_16b), // Peripheral data output |
.per_dout (per_dout_temp_16b), // Peripheral data output |
|
// INPUTs |
.mclk (mclk), // Main system clock |
.per_addr (per_addr), // Peripheral address |
.per_din (per_din), // Peripheral data input |
.per_en (per_en), // Peripheral enable (high active) |
.per_we (per_we), // Peripheral write enable (high active) |
.puc_rst (puc_rst) // Main system reset |
.mclk (mclk), // Main system clock |
.per_addr (per_addr), // Peripheral address |
.per_din (per_din), // Peripheral data input |
.per_en (per_en), // Peripheral enable (high active) |
.per_we (per_we), // Peripheral write enable (high active) |
.puc_rst (puc_rst) // Main system reset |
); |
|
|
588,33 → 620,33
// I2C Slave (openMSP430) |
//......................... |
io_cell scl_slave_inst ( |
.pad (dbg_scl), // I/O pad |
.data_in (dbg_scl_slave), // Input |
.data_out_en (1'b0), // Output enable |
.data_out (1'b0) // Output |
.pad (dbg_scl), // I/O pad |
.data_in (dbg_scl_slave), // Input |
.data_out_en (1'b0), // Output enable |
.data_out (1'b0) // Output |
); |
|
io_cell sda_slave_inst ( |
.pad (dbg_sda), // I/O pad |
.data_in (dbg_sda_slave_in), // Input |
.data_out_en (!dbg_sda_slave_out), // Output enable |
.data_out (1'b0) // Output |
.pad (dbg_sda), // I/O pad |
.data_in (dbg_sda_slave_in), // Input |
.data_out_en (!dbg_sda_slave_out), // Output enable |
.data_out (1'b0) // Output |
); |
|
// I2C Master (Debugger) |
//......................... |
io_cell scl_master_inst ( |
.pad (dbg_scl), // I/O pad |
.data_in (), // Input |
.data_out_en (!dbg_scl_master), // Output enable |
.data_out (1'b0) // Output |
.pad (dbg_scl), // I/O pad |
.data_in (), // Input |
.data_out_en (!dbg_scl_master), // Output enable |
.data_out (1'b0) // Output |
); |
|
io_cell sda_master_inst ( |
.pad (dbg_sda), // I/O pad |
.data_in (dbg_sda_master_in), // Input |
.data_out_en (!dbg_sda_master_out), // Output enable |
.data_out (1'b0) // Output |
.pad (dbg_sda), // I/O pad |
.data_in (dbg_sda_master_in), // Input |
.data_out_en (!dbg_sda_master_out), // Output enable |
.data_out (1'b0) // Output |
); |
|
|
624,17 → 656,17
msp_debug msp_debug_0 ( |
|
// OUTPUTs |
.e_state (e_state), // Execution state |
.i_state (i_state), // Instruction fetch state |
.inst_cycle (inst_cycle), // Cycle number within current instruction |
.inst_full (inst_full), // Currently executed instruction (full version) |
.inst_number (inst_number), // Instruction number since last system reset |
.inst_pc (inst_pc), // Instruction Program counter |
.inst_short (inst_short), // Currently executed instruction (short version) |
.e_state (e_state), // Execution state |
.i_state (i_state), // Instruction fetch state |
.inst_cycle (inst_cycle), // Cycle number within current instruction |
.inst_full (inst_full), // Currently executed instruction (full version) |
.inst_number (inst_number), // Instruction number since last system reset |
.inst_pc (inst_pc), // Instruction Program counter |
.inst_short (inst_short), // Currently executed instruction (short version) |
|
// INPUTs |
.mclk (mclk), // Main system clock |
.puc_rst (puc_rst) // Main system reset |
.mclk (mclk), // Main system clock |
.puc_rst (puc_rst) // Main system reset |
); |
|
|
681,6 → 713,8
$display("| SIMULATION FAILED |"); |
$display("| (simulation Timeout) |"); |
$display(" ==============================================="); |
$display(""); |
tb_extra_report; |
$finish; |
`endif |
end |
691,9 → 725,14
wait(inst_pc=='hffff); |
|
$display(" ==============================================="); |
if (error!=0) |
if ((dma_rd_error!=0) || (dma_wr_error!=0)) |
begin |
$display("| SIMULATION FAILED |"); |
$display("| (some DMA transfer failed) |"); |
end |
else if (error!=0) |
begin |
$display("| SIMULATION FAILED |"); |
$display("| (some verilog stimulus checks failed) |"); |
end |
else if (~stimulus_done) |
706,6 → 745,8
$display("| SIMULATION PASSED |"); |
end |
$display(" ==============================================="); |
$display(""); |
tb_extra_report; |
$finish; |
end |
|
722,5 → 763,32
end |
endtask |
|
task tb_extra_report; |
begin |
$display("DMA REPORT: Total Accesses: %-d Total RD: %-d Total WR: %-d", dma_cnt_rd+dma_cnt_wr, dma_cnt_rd, dma_cnt_wr); |
$display(" Total Errors: %-d Error RD: %-d Error WR: %-d", dma_rd_error+dma_wr_error, dma_rd_error, dma_wr_error); |
if (!((`PMEM_SIZE>=4092) && (`DMEM_SIZE>=1024))) |
begin |
$display(""); |
$display("Note: DMA if verification disabled (PMEM must be 4kB or bigger, DMEM must be 1kB or bigger)"); |
end |
$display(""); |
$display("SIMULATION SEED: %d", `SEED); |
$display(""); |
end |
endtask |
|
task tb_skip_finish; |
input [65*8-1:0] skip_string; |
begin |
$display(" ==============================================="); |
$display("| SIMULATION SKIPPED |"); |
$display("%s", skip_string); |
$display(" ==============================================="); |
$display(""); |
tb_extra_report; |
$finish; |
end |
endtask |
|
endmodule |
/verilog/dma_tasks.v
0,0 → 1,339
//---------------------------------------------------------------------------- |
// Copyright (C) 2014 Authors |
// |
// This source file may be used and distributed without restriction provided |
// that this copyright statement is not removed from the file and that any |
// derivative work contains the original copyright notice and the associated |
// disclaimer. |
// |
// This source file is free software; you can redistribute it and/or modify |
// it under the terms of the GNU Lesser General Public License as published |
// by the Free Software Foundation; either version 2.1 of the License, or |
// (at your option) any later version. |
// |
// This source 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 Lesser General Public |
// License for more details. |
// |
// You should have received a copy of the GNU Lesser General Public License |
// along with this source; if not, write to the Free Software Foundation, |
// Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
// |
//---------------------------------------------------------------------------- |
// |
// *File Name: dma_tasks.v |
// |
// *Module Description: |
// generic tasks for using the Direct Memory Access interface |
// |
// *Author(s): |
// - Olivier Girard, olgirard@gmail.com |
// |
//---------------------------------------------------------------------------- |
// $Rev$ |
// $LastChangedBy$ |
// $LastChangedDate$ |
//---------------------------------------------------------------------------- |
|
//============================================================================ |
// DMA Write access |
//============================================================================ |
integer dma_cnt_wr; |
integer dma_cnt_rd; |
integer dma_wr_error; |
integer dma_rd_error; |
reg dma_tfx_cancel; |
|
//--------------------- |
// Generic write task |
//--------------------- |
task dma_write; |
input [15:0] addr; // Address |
input [15:0] data; // Data |
input resp; // Expected transfer response (0: Okay / 1: Error) |
input size; // Access size (0: 8-bit / 1: 16-bit) |
|
begin |
dma_addr = addr[15:1]; |
dma_en = 1'b1; |
dma_we = size ? 2'b11 : |
addr[0] ? 2'b10 : 2'b01; |
dma_din = data; |
@(posedge mclk or posedge dma_tfx_cancel); |
while(~dma_ready & ~dma_tfx_cancel) @(posedge mclk or posedge dma_tfx_cancel); |
dma_en = 1'b0; |
dma_we = 2'b00; |
dma_addr = 15'h0000; |
dma_din = 16'h0000; |
if (~dma_tfx_cancel) dma_cnt_wr = dma_cnt_wr+1; |
|
// Check transfer response |
if (~dma_tfx_cancel & (dma_resp != resp)) |
begin |
$display("ERROR: DMA interface write response check -- address: 0x%h -- response: %h / expected: %h (%t ns)", addr, dma_resp, resp, $time); |
dma_wr_error = dma_wr_error+1; |
end |
end |
endtask |
|
//--------------------- |
// Write 16b task |
//--------------------- |
task dma_write_16b; |
input [15:0] addr; // Address |
input [15:0] data; // Data |
input resp; // Expected transfer response (0: Okay / 1: Error) |
|
begin |
dma_write(addr, data, resp, 1'b1); |
end |
endtask |
|
//--------------------- |
// Write 8b task |
//--------------------- |
task dma_write_8b; |
input [15:0] addr; // Address |
input [7:0] data; // Data |
input resp; // Expected transfer response (0: Okay / 1: Error) |
|
begin |
if (addr[0]) dma_write(addr, {data, 8'h00}, resp, 1'b0); |
else dma_write(addr, {8'h00, data }, resp, 1'b0); |
end |
endtask |
|
|
//============================================================================ |
// DMA read access |
//============================================================================ |
|
//--------------------- |
// Read check process |
//--------------------- |
reg dma_read_check_active; |
reg [15:0] dma_read_check_addr; |
reg [15:0] dma_read_check_data; |
reg [15:0] dma_read_check_mask; |
|
initial |
begin |
dma_read_check_active = 1'b0; |
dma_read_check_addr = 16'h0000; |
dma_read_check_data = 16'h0000; |
dma_read_check_mask = 16'h0000; |
forever |
begin |
@(negedge (mclk & dma_read_check_active) or posedge dma_tfx_cancel); |
if (~dma_tfx_cancel & (dma_read_check_data !== (dma_read_check_mask & dma_dout)) & ~puc_rst) |
begin |
$display("ERROR: DMA interface read check -- address: 0x%h -- read: 0x%h / expected: 0x%h (%t ns)", dma_read_check_addr, (dma_read_check_mask & dma_dout), dma_read_check_data, $time); |
dma_rd_error = dma_rd_error+1; |
end |
dma_read_check_active = 1'b0; |
end |
end |
|
//--------------------- |
// Generic read task |
//--------------------- |
task dma_read; |
input [15:0] addr; // Address |
input [15:0] data; // Data to check against |
input resp; // Expected transfer response (0: Okay / 1: Error) |
input check; // Enable/disable read value check |
input size; // Access size (0: 8-bit / 1: 16-bit) |
|
begin |
// Perform read transfer |
dma_addr = addr[15:1]; |
dma_en = 1'b1; |
dma_we = 2'b00; |
dma_din = 16'h0000; |
@(posedge mclk or posedge dma_tfx_cancel); |
while(~dma_ready & ~dma_tfx_cancel) @(posedge mclk or posedge dma_tfx_cancel); |
dma_en = 1'b0; |
dma_addr = 15'h0000; |
|
// Trigger read check |
dma_read_check_active = check; |
dma_read_check_addr = addr; |
dma_read_check_data = data; |
dma_read_check_mask = size ? 16'hFFFF : |
(addr[0] ? 16'hFF00 : 16'h00FF); |
if (~dma_tfx_cancel) dma_cnt_rd = dma_cnt_rd+1; |
|
// Check transfer response |
if (~dma_tfx_cancel & (dma_resp != resp)) |
begin |
$display("ERROR: DMA interface read response check -- address: 0x%h -- response: %h / expected: %h (%t ns)", addr, dma_resp, resp, $time); |
dma_rd_error = dma_rd_error+1; |
end |
end |
endtask |
|
//--------------------- |
// Read 16b task |
//--------------------- |
task dma_read_16b; |
input [15:0] addr; // Address |
input [15:0] data; // Data to check against |
input resp; // Expected transfer response (0: Okay / 1: Error) |
|
begin |
dma_read(addr, data, resp, 1'b1, 1'b1); |
end |
endtask |
|
//--------------------- |
// Read 8b task |
//--------------------- |
task dma_read_8b; |
input [15:0] addr; // Address |
input [7:0] data; // Data to check against |
input resp; // Expected transfer response (0: Okay / 1: Error) |
|
begin |
if (addr[0]) dma_read(addr, {data, 8'h00}, resp, 1'b1, 1'b0); |
else dma_read(addr, {8'h00, data }, resp, 1'b1, 1'b0); |
end |
endtask |
|
//-------------------------------- |
// Read 16b value task (no check) |
//-------------------------------- |
task dma_read_val_16b; |
input [15:0] addr; // Address |
input resp; // Expected transfer response (0: Okay / 1: Error) |
|
begin |
dma_read(addr, 16'h0000, resp, 1'b0, 1'b1); |
end |
endtask |
|
|
//============================================================================ |
// Ramdom DMA access process |
//============================================================================ |
|
integer dma_rand_wait; |
integer dma_rand_wait_disable; |
reg dma_rand_rdwr; |
reg dma_rand_if; |
integer dma_rand_data; |
reg [6:0] dma_rand_addr; |
reg [15:0] dma_rand_addr_full; |
integer dma_mem_ref_idx; |
reg [15:0] dma_pmem_reference[0:127]; |
reg [15:0] dma_dmem_reference[0:127]; |
reg dma_verif_on; |
reg dma_verif_verbose; |
|
initial |
begin |
// Initialize |
`ifdef NO_DMA_VERIF |
dma_verif_on = 0; |
`else |
`ifdef DMA_IF_EN |
dma_verif_on = 1; |
`else |
dma_verif_on = 0; |
`endif |
`endif |
dma_rand_wait_disable = 0; |
dma_verif_verbose = 0; |
dma_cnt_wr = 0; |
dma_cnt_rd = 0; |
dma_wr_error = 0; |
dma_rd_error = 0; |
#20; |
dma_rand_wait = $urandom; |
for (dma_mem_ref_idx=0; dma_mem_ref_idx < 128; dma_mem_ref_idx=dma_mem_ref_idx+1) |
begin |
dma_pmem_reference[dma_mem_ref_idx] = $urandom; |
dma_dmem_reference[dma_mem_ref_idx] = $urandom; |
if (dma_verif_on && (`PMEM_SIZE>=4092) && (`DMEM_SIZE>=1024)) |
begin |
pmem_0.mem[(`PMEM_SIZE-512)/2+dma_mem_ref_idx] = dma_pmem_reference[dma_mem_ref_idx]; |
dmem_0.mem[(`DMEM_SIZE-256)/2+dma_mem_ref_idx] = dma_dmem_reference[dma_mem_ref_idx]; |
end |
end |
|
// Wait for reset release |
repeat(1) @(posedge dco_clk); |
@(negedge puc_rst); |
|
// Perform random read/write 16b memory accesses |
if (dma_verif_on && (`PMEM_SIZE>=4092) && (`DMEM_SIZE>=1024)) |
begin |
forever |
begin |
// Randomize 1 or 0 wait states between accesses |
// (1/3 proba of getting 1 wait state) |
dma_rand_wait = dma_rand_wait_disable ? 0 : ($urandom_range(2,0)==0); |
repeat(dma_rand_wait) @(posedge mclk); |
|
// Randomize read/write accesses |
// (1/3 proba of getting a read access) |
dma_rand_rdwr = ($urandom_range(2,0)==0); |
|
// Randomize address to be accessed (between 128 addresses) |
dma_rand_addr = $urandom; |
|
// Randomize access through PMEM or DMEM memories |
dma_rand_if = $urandom_range(1,0); |
|
// Make sure the core is not in reset |
while(puc_rst) @(posedge mclk); |
|
if (dma_rand_rdwr) |
begin |
if (dma_rand_if) // Read from Program Memory |
begin |
dma_rand_addr_full = 16'hFE00+dma_rand_addr*2; |
if (dma_verif_verbose) $display("READ DMA interface -- address: 0x%h -- expected data: 0x%h", dma_rand_addr_full, dma_pmem_reference[dma_rand_addr]); |
dma_read_16b(dma_rand_addr_full, dma_pmem_reference[dma_rand_addr], 1'b0); |
end |
else // Read from Data Memory |
begin |
dma_rand_addr_full = `PER_SIZE+`DMEM_SIZE-256+dma_rand_addr*2; |
if (dma_verif_verbose) $display("READ DMA interface -- address: 0x%h -- expected data: 0x%h", dma_rand_addr_full, dma_dmem_reference[dma_rand_addr]); |
dma_read_16b(dma_rand_addr_full, dma_dmem_reference[dma_rand_addr], 1'b0); |
end |
end |
else |
begin |
dma_rand_data = $urandom; |
|
if (dma_rand_if) // Write to Program memory |
begin |
dma_rand_addr_full = 16'hFE00+dma_rand_addr*2; |
if (dma_verif_verbose) $display("WRITE DMA interface -- address: 0x%h -- data: 0x%h", dma_rand_addr_full, dma_rand_data[15:0]); |
dma_write_16b(dma_rand_addr_full, dma_rand_data[15:0], 1'b0); |
dma_pmem_reference[dma_rand_addr] = dma_rand_data[15:0]; |
#1; |
if (pmem_0.mem[(`PMEM_SIZE-512)/2+dma_rand_addr] !== dma_rand_data[15:0]) |
begin |
$display("ERROR: DMA interface write -- address: 0x%h -- wrote: 0x%h / expected: 0x%h (%t ns)", dma_rand_addr_full, dma_rand_data[15:0], pmem_0.mem[(`PMEM_SIZE-512)/2+dma_rand_addr], $time); |
dma_wr_error = dma_wr_error+1; |
end |
end |
else // Write to Data Memory |
begin |
dma_rand_addr_full = `PER_SIZE+`DMEM_SIZE-256+dma_rand_addr*2; |
if (dma_verif_verbose) $display("WRITE DMA interface -- address: 0x%h -- data: 0x%h", dma_rand_addr_full, dma_rand_data[15:0]); |
dma_write_16b(dma_rand_addr_full, dma_rand_data[15:0], 1'b0); |
dma_dmem_reference[dma_rand_addr] = dma_rand_data[15:0]; |
#1; |
if (dmem_0.mem[(`DMEM_SIZE-256)/2+dma_rand_addr] !== dma_rand_data[15:0]) |
begin |
$display("ERROR: DMA interface write -- address: 0x%h -- wrote: 0x%h / expected: 0x%h (%t ns)", dma_rand_addr_full, dma_rand_data[15:0], dmem_0.mem[(`DMEM_SIZE-256)/2+dma_rand_addr], $time); |
dma_wr_error = dma_wr_error+1; |
end |
end |
end |
end |
end |
end |