|  | // SPDX-License-Identifier: MIT | 
|  | // SPDX-FileCopyrightText: 2021 Tamas Hubai | 
|  |  | 
|  | `default_nettype none | 
|  |  | 
|  | module mcu_tb(); | 
|  |  | 
|  | parameter CORES = 2; | 
|  | parameter LOG_CORES = 1; | 
|  | parameter MEM_DEPTH = 16; | 
|  | parameter DATA_WIDTH = 16; | 
|  | parameter PC_WIDTH = 3; | 
|  | parameter ADDR_WIDTH = 4; | 
|  | parameter INSTR_WIDTH = 32; | 
|  | parameter INSTR_DEPTH = 4; | 
|  | parameter IN_PINS = 4; | 
|  | parameter OUT_PINS = 4; | 
|  | parameter IO_PADS = 38; | 
|  | parameter FIRST_PAD = 12; | 
|  | parameter LOGIC_PROBES = 128; | 
|  | parameter WB_WIDTH = 32; | 
|  | parameter IO_PINS = IN_PINS + OUT_PINS; | 
|  |  | 
|  | reg clk; | 
|  | wire wb_clk_i = clk; | 
|  | reg wb_rst_i; | 
|  | reg wbs_stb_i; | 
|  | reg wbs_cyc_i; | 
|  | reg wbs_we_i; | 
|  | reg [WB_WIDTH-1:0] wbs_adr_i; | 
|  | reg [WB_WIDTH-1:0] wbs_dat_i; | 
|  | wire wbs_ack_o; | 
|  | wire [WB_WIDTH-1:0] wbs_dat_o; | 
|  | reg [LOGIC_PROBES-1:0] la_data_in; | 
|  | wire [LOGIC_PROBES-1:0] la_data_out; | 
|  | reg [LOGIC_PROBES-1:0] la_oenb; | 
|  | wire [IO_PADS-1:0] io_in; | 
|  | wire [IO_PADS-1:0] io_out; | 
|  | wire [IO_PADS-1:0] io_oeb; | 
|  |  | 
|  | mcu #( | 
|  | .CORES(CORES), | 
|  | .LOG_CORES(LOG_CORES), | 
|  | .MEM_DEPTH(MEM_DEPTH), | 
|  | .DATA_WIDTH(DATA_WIDTH), | 
|  | .PC_WIDTH(PC_WIDTH), | 
|  | .ADDR_WIDTH(ADDR_WIDTH), | 
|  | .INSTR_WIDTH(INSTR_WIDTH), | 
|  | .INSTR_DEPTH(INSTR_DEPTH), | 
|  | .IO_PINS(IO_PINS), | 
|  | .IO_PADS(IO_PADS), | 
|  | .FIRST_PAD(FIRST_PAD), | 
|  | .LOGIC_PROBES(LOGIC_PROBES), | 
|  | .WB_WIDTH(WB_WIDTH) | 
|  | ) mcu_dut ( | 
|  | .wb_clk_i(wb_clk_i), | 
|  | .wb_rst_i(wb_rst_i), | 
|  | .wbs_stb_i(wbs_stb_i), | 
|  | .wbs_cyc_i(wbs_cyc_i), | 
|  | .wbs_we_i(wbs_we_i), | 
|  | .wbs_adr_i(wbs_adr_i), | 
|  | .wbs_dat_i(wbs_dat_i), | 
|  | .wbs_ack_o(wbs_ack_o), | 
|  | .wbs_dat_o(wbs_dat_o), | 
|  | .la_data_in(la_data_in), | 
|  | .la_data_out(la_data_out), | 
|  | .la_oenb(la_oenb), | 
|  | .io_in(io_in), | 
|  | .io_out(io_out), | 
|  | .io_oeb(io_oeb) | 
|  | ); | 
|  |  | 
|  | reg [IN_PINS-1:0] pin_data_in; | 
|  | assign io_in = {{(IO_PADS - IN_PINS - FIRST_PAD){1'b0}}, pin_data_in, {(FIRST_PAD){1'b0}}}; | 
|  |  | 
|  | wire [OUT_PINS-1:0] pin_data_out = io_out[FIRST_PAD + IN_PINS +: OUT_PINS]; | 
|  |  | 
|  | always #5 clk = ~clk; | 
|  |  | 
|  | initial begin | 
|  | $monitor("time %4t rh %1b rs %1b wwei %1b wai %32b pdi %4b pdo %4b", | 
|  | $time, la_data_out[1], la_data_out[2], wbs_we_i, wbs_adr_i, pin_data_in, pin_data_out); | 
|  | // power up | 
|  | clk = 0; | 
|  | wb_rst_i = 1; | 
|  | wbs_stb_i = 0; | 
|  | wbs_cyc_i = 0; | 
|  | wbs_we_i = 0; | 
|  | wbs_adr_i = 0; | 
|  | wbs_dat_i = 0; | 
|  | la_data_in = {(LOGIC_PROBES){1'b0}}; | 
|  | la_oenb = {(LOGIC_PROBES){1'b1}}; | 
|  | pin_data_in = 4'b0000; | 
|  | #10 | 
|  | // wishbone reset off, start communications | 
|  | wb_rst_i = 0; | 
|  | wbs_stb_i = 1; | 
|  | wbs_cyc_i = 1; | 
|  | wbs_we_i = 1; | 
|  | // programming mode | 
|  | wbs_adr_i = 32'b01_000000000000000000000000000000;          // set programming mode | 
|  | wbs_dat_i = 32'b00000000000000000000000000000001;           // to 1 | 
|  | #10 | 
|  | // send code for cpu core 0 | 
|  | wbs_adr_i = 32'b00_00000000000000000000000000_0_000;        // address 0: | 
|  | wbs_dat_i = 32'b100_000_1_00_0011_100_0000000000001111;     // read value from memory cell 15 (joined input) | 
|  | #10 | 
|  | wbs_adr_i = 32'b00_00000000000000000000000000_0_001;        // address 1: | 
|  | wbs_dat_i = 32'b011_000_1_11_0011_111_0000000000000001;     // write value to memory cell 0, spread 1 | 
|  | #10 | 
|  | wbs_adr_i = 32'b00_00000000000000000000000000_0_010;        // address 2: | 
|  | wbs_dat_i = 32'b100_000_1_00_0011_011_0000000000000000;     // jump to address 0 | 
|  | #10 | 
|  | // send code for cpu core 1 | 
|  | wbs_adr_i = 32'b00_00000000000000000000000000_1_000;        // address 0: | 
|  | wbs_dat_i = 32'b100_000_1_00_0011_100_0000000000000000;     // read value from memory cell 0 | 
|  | #10 | 
|  | wbs_adr_i = 32'b00_00000000000000000000000000_1_001;        // address 1: | 
|  | wbs_dat_i = 32'b011_000_1_11_0011_111_0000000011100010;     // write value to memory cell 14, spread 2 (joined output) | 
|  | #10 | 
|  | wbs_adr_i = 32'b00_00000000000000000000000000_1_010;        // address 2: | 
|  | wbs_dat_i = 32'b100_000_1_00_0011_011_0000000000000000;     // jump to address 0 | 
|  | #10 | 
|  | // set pin directions | 
|  | wbs_adr_i = 32'b01_000000000000000000000000000001;          // set pin directions | 
|  | wbs_dat_i = 32'b00000000000000000000000011110000;           // first 4 pins are inputs, next 4 pins are outputs | 
|  | #10 | 
|  | // exit programming mode | 
|  | wbs_adr_i = 32'b01_000000000000000000000000000000;          // set programming mode | 
|  | wbs_dat_i = 32'b00000000000000000000000000000000;           // to 0 | 
|  | #10 | 
|  | // stop wishbone communications | 
|  | wbs_we_i = 0; | 
|  | wbs_cyc_i = 0; | 
|  | wbs_stb_i = 0; | 
|  | // set input pins | 
|  | pin_data_in = 4'b0011; | 
|  | // wait for data to appear on output pins | 
|  | #100 | 
|  | // change input pins | 
|  | pin_data_in = 4'b1001; | 
|  | // wait for data to appear on output pins | 
|  | #100 | 
|  | // change input pins | 
|  | pin_data_in = 4'b1100; | 
|  | // wait for data to appear on output pins | 
|  | #100 | 
|  | $stop; | 
|  | end | 
|  |  | 
|  | endmodule | 
|  |  | 
|  | `default_nettype wire | 
|  |  |