URL
https://opencores.org/ocsvn/xgate/xgate/trunk
Subversion Repositories xgate
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 61 to Rev 62
- ↔ Reverse comparison
Rev 61 → Rev 62
/xgate/trunk/bench/verilog/tst_bench_top.v
3,7 → 3,7
// WISHBONE revB.2 compliant Xgate Coprocessor - Test Bench |
// |
// Author: Bob Hayes |
// rehayes@opencores.org |
// rehayes@opencores.org |
// |
// Downloaded from: http://www.opencores.org/projects/xgate..... |
// |
17,10 → 17,10
// |
// Supplemental terms. |
// * Redistributions of source code must retain the above copyright |
// notice, this list of conditions and the following disclaimer. |
// notice, this list of conditions and the following disclaimer. |
// * Neither the name of the <organization> nor the |
// names of its contributors may be used to endorse or promote products |
// derived from this software without specific prior written permission. |
// names of its contributors may be used to endorse or promote products |
// derived from this software without specific prior written permission. |
// |
// THIS SOFTWARE IS PROVIDED BY Robert Hayes ''AS IS'' AND ANY |
// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
43,7 → 43,7
|
module tst_bench_top(); |
|
parameter MAX_CHANNEL = 127; // Max XGATE Interrupt Channel Number |
parameter MAX_CHANNEL = 127; // Max XGATE Interrupt Channel Number |
parameter STOP_ON_ERROR = 1'b0; |
parameter MAX_VECTOR = 8000; |
|
53,12 → 53,12
|
|
// Name Address Locations |
parameter XGATE_BASE = 24'h1000; |
parameter XGATE_BASE = 24'h1000; |
parameter XGATE_XGMCTL = XGATE_BASE + 6'h00; |
parameter XGATE_XGCHID = XGATE_BASE + 6'h02; |
parameter XGATE_XGISPHI = XGATE_BASE + 6'h04; |
parameter XGATE_XGISPLO = XGATE_BASE + 6'h06; |
parameter XGATE_XGVBR = XGATE_BASE + 6'h08; |
parameter XGATE_XGVBR = XGATE_BASE + 6'h08; |
parameter XGATE_XGIF_7 = XGATE_BASE + 6'h0a; |
parameter XGATE_XGIF_6 = XGATE_BASE + 6'h0c; |
parameter XGATE_XGIF_5 = XGATE_BASE + 6'h0e; |
67,22 → 67,22
parameter XGATE_XGIF_2 = XGATE_BASE + 6'h14; |
parameter XGATE_XGIF_1 = XGATE_BASE + 6'h16; |
parameter XGATE_XGIF_0 = XGATE_BASE + 6'h18; |
parameter XGATE_XGSWT = XGATE_BASE + 6'h1a; |
parameter XGATE_XGSEM = XGATE_BASE + 6'h1c; |
parameter XGATE_RES1 = XGATE_BASE + 6'h1e; |
parameter XGATE_XGCCR = XGATE_BASE + 6'h20; |
parameter XGATE_XGPC = XGATE_BASE + 6'h22; |
parameter XGATE_RES2 = XGATE_BASE + 6'h24; |
parameter XGATE_XGR1 = XGATE_BASE + 6'h26; |
parameter XGATE_XGR2 = XGATE_BASE + 6'h28; |
parameter XGATE_XGR3 = XGATE_BASE + 6'h2a; |
parameter XGATE_XGR4 = XGATE_BASE + 6'h2c; |
parameter XGATE_XGR5 = XGATE_BASE + 6'h2e; |
parameter XGATE_XGR6 = XGATE_BASE + 6'h30; |
parameter XGATE_XGR7 = XGATE_BASE + 6'h32; |
parameter XGATE_XGSWT = XGATE_BASE + 6'h1a; |
parameter XGATE_XGSEM = XGATE_BASE + 6'h1c; |
parameter XGATE_RES1 = XGATE_BASE + 6'h1e; |
parameter XGATE_XGCCR = XGATE_BASE + 6'h20; |
parameter XGATE_XGPC = XGATE_BASE + 6'h22; |
parameter XGATE_RES2 = XGATE_BASE + 6'h24; |
parameter XGATE_XGR1 = XGATE_BASE + 6'h26; |
parameter XGATE_XGR2 = XGATE_BASE + 6'h28; |
parameter XGATE_XGR3 = XGATE_BASE + 6'h2a; |
parameter XGATE_XGR4 = XGATE_BASE + 6'h2c; |
parameter XGATE_XGR5 = XGATE_BASE + 6'h2e; |
parameter XGATE_XGR6 = XGATE_BASE + 6'h30; |
parameter XGATE_XGR7 = XGATE_BASE + 6'h32; |
|
// Define bits in XGATE Control Register |
parameter XGMCTL_XGEM = 16'h8000; |
parameter XGMCTL_XGEM = 16'h8000; |
parameter XGMCTL_XGFRZM = 16'h4000; |
parameter XGMCTL_XGDBGM = 15'h2000; |
parameter XGMCTL_XGSSM = 15'h1000; |
90,57 → 90,62
parameter XGMCTL_XGBRKIEM = 15'h0400; |
parameter XGMCTL_XGSWEIFM = 15'h0200; |
parameter XGMCTL_XGIEM = 15'h0100; |
parameter XGMCTL_XGE = 16'h0080; |
parameter XGMCTL_XGE = 16'h0080; |
parameter XGMCTL_XGFRZ = 16'h0040; |
parameter XGMCTL_XGDBG = 15'h0020; |
parameter XGMCTL_XGSS = 15'h0010; |
parameter XGMCTL_XGSS = 15'h0010; |
parameter XGMCTL_XGFACT = 15'h0008; |
parameter XGMCTL_XGBRKIE = 15'h0004; |
parameter XGMCTL_XGSWEIF = 15'h0002; |
parameter XGMCTL_XGIE = 15'h0001; |
parameter XGMCTL_XGIE = 15'h0001; |
|
parameter CHECK_POINT = 16'h8000; |
parameter CHANNEL_ACK = CHECK_POINT + 2; |
parameter CHANNEL_ERR = CHECK_POINT + 4; |
|
parameter SYS_RAM_BASE = 24'h0000_0000; |
|
parameter SYS_RAM_BASE = 24'h00_0000; |
|
// |
// wires && regs |
// |
reg mstr_test_clk; |
reg mstr_test_clk; |
reg [19:0] vector; |
reg [15:0] error_count; |
reg [ 7:0] test_num; |
|
|
reg [15:0] q, qq; |
|
reg rstn; |
reg sync_reset; |
reg por_reset_b; |
reg stop_mode; |
reg wait_mode; |
reg debug_mode; |
reg scantestmode; |
reg rstn; |
reg sync_reset; |
reg por_reset_b; |
reg scantestmode; |
|
wire [15:0] dat_i; |
wire ack; |
|
reg [MAX_CHANNEL:0] channel_req; // XGATE Interrupt inputs |
wire [MAX_CHANNEL:0] xgif; // XGATE Interrupt outputs |
wire [ 7:0] xgswt; // XGATE Software Trigger outputs |
wire xg_sw_irq; // Xgate Software Error interrupt |
wire [MAX_CHANNEL:0] xgif; // XGATE Interrupt outputs |
wire [ 7:0] xgswt; // XGATE Software Trigger outputs |
wire xg_sw_irq; // Xgate Software Error interrupt |
|
|
wire [15:0] wbm_dat_o; // WISHBONE Master Mode data output from XGATE |
wire [15:0] wbm_dat_i; // WISHBONE Master Mode data input to XGATE |
wire [15:0] wbm_adr_o; // WISHBONE Master Mode address output from XGATE |
wire [15:0] wbm_dat_o; // WISHBONE Master Mode data output from XGATE |
wire [15:0] wbm_dat_i; // WISHBONE Master Mode data input to XGATE |
wire [15:0] wbm_adr_o; // WISHBONE Master Mode address output from XGATE |
wire [ 1:0] wbm_sel_o; |
|
reg mem_wait_state_enable; |
reg mem_wait_state_enable; |
|
wire [15:0] tb_ram_out; |
|
wire [15:0] tb_slave_dout; // WISHBONE data bus output from testbench slave module |
wire error_pulse; // Error detected output pulse from the testbench slave module |
wire test_reg_ack; // WISHBONE ack from testbench slave module |
wire ack_pulse; // Thread ack output pulse from testbench slave module |
|
wire wbm_cyc_o; |
wire wbm_stb_o; |
wire wbm_we_o; |
wire wbs_err_o; |
|
|
// Registers used to mirror internal registers |
reg [15:0] data_xgmctl; |
reg [15:0] data_xgchid; |
148,38 → 153,38
reg [15:0] data_xgswt; |
reg [15:0] data_xgsem; |
|
wire sys_cyc; |
wire sys_stb; |
wire sys_we; |
wire sys_cyc; |
wire sys_stb; |
wire sys_we; |
wire [ 1:0] sys_sel; |
wire [23:0] sys_adr; |
wire [15:0] sys_dout; |
wire [15:0] sys_din; |
|
wire host_ack; |
|
wire host_ack; |
wire [15:0] host_dout; |
wire host_cyc; |
wire host_stb; |
wire host_we; |
wire host_cyc; |
wire host_stb; |
wire host_we; |
wire [ 1:0] host_sel; |
wire [23:0] host_adr; |
wire [15:0] host_din; |
|
wire xgate_ack; |
|
wire xgate_ack; |
wire [15:0] xgate_dout; |
wire xgate_cyc; |
wire xgate_stb; |
wire xgate_we; |
wire xgate_cyc; |
wire xgate_stb; |
wire xgate_we; |
wire [ 1:0] xgate_sel; |
wire [15:0] xgate_adr; |
wire [15:0] xgate_din; |
|
wire xgate_s_stb; |
wire xgate_s_ack; |
|
wire xgate_s_stb; |
wire xgate_s_ack; |
wire [15:0] xgate_s_dout; |
|
wire slv2_stb; |
wire ram_sel; |
|
wire slv2_stb; |
wire ram_sel; |
wire [15:0] ram_dout; |
|
// initial values and testbench setup |
189,9 → 194,6
vector = 0; |
test_num = 0; |
por_reset_b = 0; |
stop_mode = 0; |
wait_mode = 0; |
debug_mode = 0; |
scantestmode = 0; |
error_count = 0; |
mem_wait_state_enable = 0; |
198,16 → 200,16
// channel_req = 0; |
|
`ifdef WAVES |
$shm_open("waves"); |
$shm_probe("AS",tst_bench_top,"AS"); |
$display("\nINFO: Signal dump enabled ...\n\n"); |
$shm_open("waves"); |
$shm_probe("AS",tst_bench_top,"AS"); |
$display("\nINFO: Signal dump enabled ...\n\n"); |
`endif |
|
`ifdef WAVES_V |
$dumpfile ("xgate_wave_dump.lxt"); |
$dumpvars (0, tst_bench_top); |
$dumpon; |
$display("\nINFO: VCD Signal dump enabled ...\n\n"); |
$dumpfile ("xgate_wave_dump.lxt"); |
$dumpvars (0, tst_bench_top); |
$dumpon; |
$display("\nINFO: VCD Signal dump enabled ...\n\n"); |
`endif |
|
end |
220,11 → 222,11
begin |
vector <= vector + 1; |
if (vector > MAX_VECTOR) |
begin |
error_count <= error_count + 1; |
$display("\n ------ !!!!! Simulation Timeout at vector=%d\n -------", vector); |
wrap_up; |
end |
begin |
error_count <= error_count + 1; |
$display("\n ------ !!!!! Simulation Timeout at vector=%d\n -------", vector); |
wrap_up; |
end |
end |
|
// Add up errors that come from WISHBONE read compares |
238,7 → 240,7
#1; |
error_count = error_count + 1; |
if (STOP_ON_ERROR == 1'b1) |
wrap_up; |
wrap_up; |
end |
|
wire [ 6:0] current_active_channel = xgate.risc.xgchid; |
245,8 → 247,8
always @(posedge ack_pulse) //channel_ack_wrt |
clear_channel(current_active_channel); |
|
|
|
|
// Testbench RAM for Xgate program storage and Load/Store instruction tests |
ram p_ram |
( |
281,7 → 283,7
); |
|
bus_arbitration #(.dwidth(16), |
.awidth(24), |
.awidth(24), |
.ram_base(0), |
.ram_size(17'h10000), |
.slv1_base(XGATE_BASE), |
324,7 → 326,7
// Slave #2 Bus I/O |
.slv2_stb( slv2_stb ), |
.slv2_ack( test_reg_ack ), |
.slv2_din( ram_dout ), |
.slv2_din( tb_slave_dout ), |
// Miscellaneous |
.host_clk( mstr_test_clk ), |
.risc_clk( mstr_test_clk ), |
332,45 → 334,47
.err( 1'b0 ), // No Connect |
.rty( 1'b0 ) // No Connect |
); |
|
|
// hookup XGATE core - Parameters take all default values |
xgate_top #(.SINGLE_CYCLE(1'b0), |
.MAX_CHANNEL(MAX_CHANNEL)) // Max XGATE Interrupt Channel Number |
xgate( |
// Wishbone slave interface |
.wbs_clk_i( mstr_test_clk ), |
.wbs_rst_i( 1'b0 ), // sync_reset |
.arst_i( rstn ), // async resetn |
.wbs_adr_i( sys_adr[5:1] ), |
.wbs_dat_i( sys_dout ), |
.wbs_dat_o( xgate_s_dout ), |
.wbs_we_i( sys_we ), |
.wbs_stb_i( xgate_s_stb ), |
.wbs_cyc_i( sys_cyc ), |
.wbs_sel_i( sys_sel ), |
.wbs_ack_o( xgate_s_ack ), |
.wbs_err_o( wbs_err_o ), |
.MAX_CHANNEL(MAX_CHANNEL)) // Max XGATE Interrupt Channel Number |
xgate( |
// Wishbone slave interface |
.wbs_clk_i( mstr_test_clk ), |
.wbs_rst_i( 1'b0 ), // sync_reset |
.arst_i( rstn ), // async resetn |
.wbs_adr_i( sys_adr[5:1] ), |
.wbs_dat_i( sys_dout ), |
.wbs_dat_o( xgate_s_dout ), |
.wbs_we_i( sys_we ), |
.wbs_stb_i( xgate_s_stb ), |
.wbs_cyc_i( sys_cyc ), |
.wbs_sel_i( sys_sel ), |
.wbs_ack_o( xgate_s_ack ), |
.wbs_err_o( wbs_err_o ), |
|
// Wishbone master Signals |
.wbm_dat_o( wbm_dat_o ), |
.wbm_we_o( wbm_we_o ), |
.wbm_stb_o( wbm_stb_o ), |
.wbm_cyc_o( wbm_cyc_o ), |
.wbm_sel_o( wbm_sel_o ), |
.wbm_adr_o( wbm_adr_o ), |
.wbm_dat_i( sys_din ), |
.wbm_ack_i( xgate_ack ), |
// Wishbone master Signals |
.wbm_dat_o( wbm_dat_o ), |
.wbm_we_o( wbm_we_o ), |
.wbm_stb_o( wbm_stb_o ), |
.wbm_cyc_o( wbm_cyc_o ), |
.wbm_sel_o( wbm_sel_o ), |
.wbm_adr_o( wbm_adr_o ), |
.wbm_dat_i( sys_din ), |
.wbm_ack_i( xgate_ack ), |
|
.xgif( xgif ), // XGATE Interrupt Flag output |
.xg_sw_irq( xg_sw_irq ), // XGATE Software Error Interrupt Flag output |
.xgswt( xgswt ), |
.risc_clk( mstr_test_clk ), |
.chan_req_i( {channel_req[MAX_CHANNEL:40], xgswt, channel_req[31:0]} ), |
.scantestmode( scantestmode ) |
.xgif( xgif ), // XGATE Interrupt Flag output |
.xg_sw_irq( xg_sw_irq ), // XGATE Software Error Interrupt Flag output |
.xgswt( xgswt ), |
.risc_clk( mstr_test_clk ), |
.chan_req_i( {channel_req[MAX_CHANNEL:40], xgswt, channel_req[31:0]} ), |
.debug_mode_i( 1'b0 ), |
.secure_mode_i( 1'b0 ), |
.scantestmode( scantestmode ) |
); |
|
tb_slave #(.DWIDTH(16), |
.SINGLE_CYCLE(1'b1)) |
.SINGLE_CYCLE(1'b1)) |
tb_slave_regs( |
// wishbone interface |
.wb_clk_i( mstr_test_clk ), |
378,7 → 382,7
.arst_i( rstn ), |
.wb_adr_i( sys_adr[3:1] ), |
.wb_dat_i( sys_dout ), |
.wb_dat_o(), |
.wb_dat_o( tb_slave_dout), |
.wb_we_i( sys_we ), |
.wb_stb_i( slv2_stb ), |
.wb_cyc_i( sys_cyc ), |
385,7 → 389,7
.wb_sel_i( sys_sel ), |
.wb_ack_o( test_reg_ack ), |
|
.ack_pulse( ack_pulse ), |
.ack_pulse( ack_pulse ), |
.error_pulse( error_pulse ), |
.vector( vector ) |
); |
405,10 → 409,10
rstn = 1'b1; // negate reset |
channel_req = 1; // |
repeat(1) @(posedge mstr_test_clk); |
sync_reset = 1'b1; // Make the sync reset 1 clock cycle long |
#2; // move the async reset away from the clock edge |
sync_reset = 1'b1; // Make the sync reset 1 clock cycle long |
#2; // move the async reset away from the clock edge |
rstn = 1'b0; // assert async reset |
#5; // Keep the async reset pulse with less than a clock cycle |
#5; // Keep the async reset pulse with less than a clock cycle |
rstn = 1'b1; // negate async reset |
por_reset_b = 1'b1; |
channel_req = 0; // |
443,62 → 447,62
$readmemh("../../../bench/verilog/debug_test.v", p_ram.ram_8); |
|
data_xgmctl = XGMCTL_XGBRKIEM | XGMCTL_XGBRKIE; |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Enable interrupt on BRK instruction |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Enable interrupt on BRK instruction |
|
activate_thread_sw(3); |
|
wait_debug_set; // Debug Status bit is set by BRK instruction |
|
host.wb_cmp(0, XGATE_XGPC, 16'h20c6, WORD); // See Program code (BRK). |
host.wb_cmp(0, XGATE_XGR3, 16'h0001, WORD); // See Program code.R3 = 1 |
host.wb_cmp(0, XGATE_XGCHID, 16'h0003, WORD); // Check for Correct CHID |
host.wb_cmp(0, XGATE_XGPC, 16'h20c6, WORD); // See Program code (BRK). |
host.wb_cmp(0, XGATE_XGR3, 16'h0001, WORD); // See Program code.R3 = 1 |
host.wb_cmp(0, XGATE_XGCHID, 16'h0003, WORD); // Check for Correct CHID |
|
channel_req[5] = 1'b1; // |
repeat(7) @(posedge mstr_test_clk); |
host.wb_cmp(0, XGATE_XGCHID, 16'h0003, WORD); // Check for Correct CHID |
host.wb_cmp(0, XGATE_XGCHID, 16'h0003, WORD); // Check for Correct CHID |
|
host.wb_write(0, XGATE_XGCHID, 16'h000f, H_BYTE); // Check byte select lines |
host.wb_write(0, XGATE_XGCHID, 16'h000f, H_BYTE); // Check byte select lines |
repeat(4) @(posedge mstr_test_clk); |
host.wb_cmp(0, XGATE_XGCHID, 16'h0003, WORD); // Verify CHID is unchanged |
|
host.wb_write(0, XGATE_XGCHID, 16'h000f, L_BYTE); // Change CHID |
host.wb_cmp(0, XGATE_XGCHID, 16'h000f, WORD); // Check for Correct CHID |
host.wb_cmp(0, XGATE_XGCHID, 16'h0003, WORD); // Verify CHID is unchanged |
|
host.wb_write(0, XGATE_XGCHID, 16'h0000, WORD); // Change CHID to 00, RISC should go to IDLE state |
host.wb_write(0, XGATE_XGCHID, 16'h000f, L_BYTE); // Change CHID |
host.wb_cmp(0, XGATE_XGCHID, 16'h000f, WORD); // Check for Correct CHID |
|
host.wb_write(0, XGATE_XGCHID, 16'h0000, WORD); // Change CHID to 00, RISC should go to IDLE state |
|
repeat(1) @(posedge mstr_test_clk); |
|
host.wb_write(0, XGATE_XGCHID, 16'h0004, WORD); // Change CHID |
host.wb_write(0, XGATE_XGCHID, 16'h0004, WORD); // Change CHID |
|
repeat(8) @(posedge mstr_test_clk); |
|
data_xgmctl = XGMCTL_XGDBGM; |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Clear Debug Mode Control Bit |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Clear Debug Mode Control Bit |
|
wait_debug_set; // Debug Status bit is set by BRK instruction |
host.wb_cmp(0, XGATE_XGCHID, 16'h0004, WORD); // Check for Correct CHID |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Clear Debug Mode Control Bit (Excape from Break State and run) |
host.wb_cmp(0, XGATE_XGCHID, 16'h0004, WORD); // Check for Correct CHID |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Clear Debug Mode Control Bit (Excape from Break State and run) |
|
wait_debug_set; // Debug Status bit is set by BRK instruction |
host.wb_cmp(0, XGATE_XGCHID, 16'h0005, WORD); // Check for Correct CHID |
host.wb_cmp(0, XGATE_XGCHID, 16'h0005, WORD); // Check for Correct CHID |
activate_channel(6); |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Clear Debug Mode Control Bit (Excape from Break State and run) |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Clear Debug Mode Control Bit (Excape from Break State and run) |
|
wait_debug_set; // Debug Status bit is set by BRK instruction |
host.wb_cmp(0, XGATE_XGCHID, 16'h0006, WORD); // Check for Correct CHID |
host.wb_cmp(0, XGATE_XGPC, 16'h211c, WORD); // See Program code (BRK) |
host.wb_cmp(0, XGATE_XGCHID, 16'h0006, WORD); // Check for Correct CHID |
host.wb_cmp(0, XGATE_XGPC, 16'h211c, WORD); // See Program code (BRK) |
data_xgmctl = XGMCTL_XGSSM | XGMCTL_XGSS; |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step |
repeat(8) @(posedge mstr_test_clk); |
host.wb_cmp(0, XGATE_XGPC, 16'h211e, WORD); // See Program code (BRA) |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step |
host.wb_cmp(0, XGATE_XGPC, 16'h211e, WORD); // See Program code (BRA) |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step |
repeat(8) @(posedge mstr_test_clk); |
host.wb_cmp(0, XGATE_XGPC, 16'h2122, WORD); // See Program code () |
host.wb_cmp(0, XGATE_XGPC, 16'h2122, WORD); // See Program code () |
|
repeat(20) @(posedge mstr_test_clk); |
|
data_xgmctl = XGMCTL_XGDBGM; |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Clear Debug Mode Control Bit |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Clear Debug Mode Control Bit |
|
repeat(50) @(posedge mstr_test_clk); |
|
533,7 → 537,7
$readmemh("../../../bench/verilog/debug_test.v", p_ram.ram_8); |
|
data_xgmctl = XGMCTL_XGBRKIEM | XGMCTL_XGBRKIE; |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Enable interrupt on BRK instruction |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Enable interrupt on BRK instruction |
|
activate_thread_sw(2); |
|
540,7 → 544,7
repeat(25) @(posedge mstr_test_clk); |
|
data_xgmctl = XGMCTL_XGDBGM | XGMCTL_XGDBG; |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Set Debug Mode Control Bit |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Set Debug Mode Control Bit |
repeat(5) @(posedge mstr_test_clk); |
|
host.wb_read(1, XGATE_XGR3, q, WORD); |
550,32 → 554,32
// The Xgate test program is in an infinate loop incrementing R3 |
while (qq == q) // Look for change in R3 register |
begin |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step |
repeat(7) @(posedge mstr_test_clk); |
host.wb_read(1, XGATE_XGR3, q, WORD); |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step |
repeat(7) @(posedge mstr_test_clk); |
host.wb_read(1, XGATE_XGR3, q, WORD); |
end |
if (q != (qq+1)) |
begin |
$display("Error! - Unexpected value of R3 at vector=%d", vector); |
error_count = error_count + 1; |
$display("Error! - Unexpected value of R3 at vector=%d", vector); |
error_count = error_count + 1; |
end |
|
|
host.wb_write(1, XGATE_XGPC, 16'h2094, WORD); // Write to PC to force exit from infinite loop |
host.wb_write(1, XGATE_XGPC, 16'h2094, WORD); // Write to PC to force exit from infinite loop |
repeat(10) @(posedge mstr_test_clk); |
|
data_xgmctl = XGMCTL_XGSSM | XGMCTL_XGSS; |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (Load ADDL instruction) |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (Load ADDL instruction) |
repeat(10) @(posedge mstr_test_clk); |
host.wb_cmp(0, XGATE_XGR4, 16'h0002, WORD); // See Program code.(R4 <= R4 + 1) |
host.wb_cmp(0, XGATE_XGR4, 16'h0002, WORD); // See Program code.(R4 <= R4 + 1) |
|
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (Load ADDL instruction) |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (Load ADDL instruction) |
repeat(10) @(posedge mstr_test_clk); |
host.wb_cmp(0, XGATE_XGR4, 16'h0003, WORD); // See Program code.(R4 <= R4 + 1) |
host.wb_cmp(0, XGATE_XGR4, 16'h0003, WORD); // See Program code.(R4 <= R4 + 1) |
|
data_xgmctl = XGMCTL_XGDBGM; |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Clear Debug Mode Control Bit |
// Should be back in Run Mode |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Clear Debug Mode Control Bit |
// Should be back in Run Mode |
|
// data_xgmctl = XGMCTL_XGSWEIFM | XGMCTL_XGSWEIF | XGMCTL_XGBRKIEM; |
// host.wb_write(0, XGATE_XGMCTL, data_xgmctl); // Clear Software Interrupt and BRK Interrupt Enable Bit |
593,73 → 597,73
$readmemh("../../../bench/verilog/debug_test.v", p_ram.ram_8); |
|
data_xgmctl = XGMCTL_XGBRKIEM | XGMCTL_XGBRKIE; |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Enable interrupt on BRK instruction |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Enable interrupt on BRK instruction |
|
activate_thread_sw(1); |
|
wait_debug_set; // Debug Status bit is set by BRK instruction |
|
host.wb_cmp(0, XGATE_XGPC, 16'h203a, WORD); // See Program code (BRK). |
host.wb_cmp(0, XGATE_XGR3, 16'h0001, WORD); // See Program code.R3 = 1 |
host.wb_cmp(0, XGATE_XGPC, 16'h203a, WORD); // See Program code (BRK). |
host.wb_cmp(0, XGATE_XGR3, 16'h0001, WORD); // See Program code.R3 = 1 |
|
data_xgmctl = XGMCTL_XGSSM | XGMCTL_XGSS; |
|
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (Load ADDL instruction) |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (Load ADDL instruction) |
repeat(5) @(posedge mstr_test_clk); |
host.wb_cmp(0, XGATE_XGPC, 16'h203c, WORD); // PC + 2. |
host.wb_cmp(0, XGATE_XGPC, 16'h203c, WORD); // PC + 2. |
|
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (Load NOP instruction) |
repeat(5) @(posedge mstr_test_clk); // Execute ADDL instruction |
host.wb_cmp(0, XGATE_XGR3, 16'h0002, WORD); // See Program code.(R3 <= R3 + 1) |
host.wb_cmp(0, XGATE_XGCCR, 16'h0000, WORD); // See Program code. |
host.wb_cmp(0, XGATE_XGPC, 16'h203e, WORD); // PC + 2. |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (Load NOP instruction) |
repeat(5) @(posedge mstr_test_clk); // Execute ADDL instruction |
host.wb_cmp(0, XGATE_XGR3, 16'h0002, WORD); // See Program code.(R3 <= R3 + 1) |
host.wb_cmp(0, XGATE_XGCCR, 16'h0000, WORD); // See Program code. |
host.wb_cmp(0, XGATE_XGPC, 16'h203e, WORD); // PC + 2. |
repeat(5) @(posedge mstr_test_clk); |
host.wb_cmp(0, XGATE_XGPC, 16'h203e, WORD); // Still no change. |
host.wb_cmp(0, XGATE_XGPC, 16'h203e, WORD); // Still no change. |
|
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (Load BRA instruction) |
repeat(9) @(posedge mstr_test_clk); // Execute NOP instruction |
host.wb_cmp(0, XGATE_XGPC, 16'h2040, WORD); // See Program code. |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (Load BRA instruction) |
repeat(9) @(posedge mstr_test_clk); // Execute NOP instruction |
host.wb_cmp(0, XGATE_XGPC, 16'h2040, WORD); // See Program code. |
|
|
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step |
repeat(5) @(posedge mstr_test_clk); // Execute BRA instruction |
host.wb_cmp(0, XGATE_XGPC, 16'h2064, WORD); // PC = Branch destination. |
// Load ADDL instruction |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step |
repeat(5) @(posedge mstr_test_clk); // Execute BRA instruction |
host.wb_cmp(0, XGATE_XGPC, 16'h2064, WORD); // PC = Branch destination. |
// Load ADDL instruction |
|
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (Load LDW R7 instruction) |
repeat(5) @(posedge mstr_test_clk); // Execute ADDL instruction |
host.wb_cmp(0, XGATE_XGPC, 16'h2066, WORD); // PC + 2. |
host.wb_cmp(0, XGATE_XGR3, 16'h0003, WORD); // See Program code.(R3 <= R3 + 1) |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (Load LDW R7 instruction) |
repeat(5) @(posedge mstr_test_clk); // Execute ADDL instruction |
host.wb_cmp(0, XGATE_XGPC, 16'h2066, WORD); // PC + 2. |
host.wb_cmp(0, XGATE_XGR3, 16'h0003, WORD); // See Program code.(R3 <= R3 + 1) |
|
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (LDW R7) |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (LDW R7) |
repeat(5) @(posedge mstr_test_clk); |
host.wb_cmp(0, XGATE_XGPC, 16'h2068, WORD); // PC + 2. |
host.wb_cmp(0, XGATE_XGR7, 16'h00c3, WORD); // See Program code |
host.wb_cmp(0, XGATE_XGPC, 16'h2068, WORD); // PC + 2. |
host.wb_cmp(0, XGATE_XGR7, 16'h00c3, WORD); // See Program code |
|
repeat(1) @(posedge mstr_test_clk); |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (BRA) |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (BRA) |
repeat(9) @(posedge mstr_test_clk); |
host.wb_cmp(0, XGATE_XGPC, 16'h2048, WORD); // See Program code. |
host.wb_cmp(0, XGATE_XGPC, 16'h2048, WORD); // See Program code. |
|
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (STW R3) |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (STW R3) |
repeat(5) @(posedge mstr_test_clk); |
host.wb_cmp(0, XGATE_XGPC, 16'h204a, WORD); // PC + 2. |
host.wb_cmp(0, XGATE_XGR3, 16'h0003, WORD); // See Program code.(R3 <= R3 + 1) |
host.wb_cmp(0, XGATE_XGPC, 16'h204a, WORD); // PC + 2. |
host.wb_cmp(0, XGATE_XGR3, 16'h0003, WORD); // See Program code.(R3 <= R3 + 1) |
|
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (R3 <= R3 + 1) |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step (R3 <= R3 + 1) |
repeat(5) @(posedge mstr_test_clk); |
host.wb_cmp(0, XGATE_XGPC, 16'h204c, WORD); // PC + 2. |
host.wb_cmp(0, XGATE_XGPC, 16'h204c, WORD); // PC + 2. |
|
repeat(5) @(posedge mstr_test_clk); |
|
data_xgmctl = XGMCTL_XGDBGM; |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Clear Debug Mode Control Bit |
// Should be back in Run Mode |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Clear Debug Mode Control Bit |
// Should be back in Run Mode |
wait_irq_set(1); |
host.wb_write(1, XGATE_XGIF_0, 16'h0002, WORD); |
|
data_xgmctl = XGMCTL_XGSWEIFM | XGMCTL_XGSWEIF | XGMCTL_XGBRKIEM; |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Clear Software Interrupt and BRK Interrupt Enable Bit |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Clear Software Interrupt and BRK Interrupt Enable Bit |
repeat(15) @(posedge mstr_test_clk); |
|
end |
711,22 → 715,22
host.wb_write(1, XGATE_XGIF_0, 16'h0200, WORD); |
|
host.wb_write(1, XGATE_XGSEM, 16'h5050, WORD); |
host.wb_cmp(0, XGATE_XGSEM, 16'h0050, WORD); // |
host.wb_cmp(0, XGATE_XGSEM, 16'h0050, WORD); // |
activate_thread_sw(10); |
wait_irq_set(10); |
host.wb_write(1, XGATE_XGIF_0, 16'h0400, WORD); |
|
host.wb_write(1, XGATE_XGSEM, 16'hff00, WORD); // clear the old settings |
host.wb_cmp(0, XGATE_XGSEM, 16'h0000, WORD); // |
host.wb_cmp(0, XGATE_XGSEM, 16'h0000, WORD); // |
host.wb_write(1, XGATE_XGSEM, 16'ha0a0, WORD); // Verify that bits were unlocked by RISC |
host.wb_cmp(0, XGATE_XGSEM, 16'h00a0, WORD); // Verify bits were set |
host.wb_cmp(0, XGATE_XGSEM, 16'h00a0, WORD); // Verify bits were set |
host.wb_write(1, XGATE_XGSEM, 16'hff08, WORD); // Try to set the bit that was left locked by the RISC |
host.wb_cmp(0, XGATE_XGSEM, 16'h0000, WORD); // Verify no bits were set |
host.wb_cmp(0, XGATE_XGSEM, 16'h0000, WORD); // Verify no bits were set |
|
repeat(20) @(posedge mstr_test_clk); |
|
p_ram.dump_ram(0); |
|
|
read_ram_cmp(16'h0000,16'haa55); |
read_ram_cmp(16'h0004,16'h7faa); |
read_ram_cmp(16'h0006,16'h6f55); |
739,9 → 743,9
read_ram_cmp(16'h0026,16'hxx99); |
read_ram_cmp(16'h0052,16'hxx66); |
read_ram_cmp(16'h0058,16'h99xx); |
|
|
data_xgmctl = 16'hff00; |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Disable XGATE |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Disable XGATE |
|
end |
endtask |
754,32 → 758,32
$display("TEST #%d Starts at vector=%d, reg_test_16", test_num, vector); |
|
system_reset; |
|
host.wb_cmp(0, XGATE_XGMCTL, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGCHID, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGISPHI, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGISPLO, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGVBR, 16'hfe00, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_7, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_6, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_5, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_4, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_3, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_2, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_1, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_0, 16'h0001, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGSWT, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGSEM, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGCCR, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGPC, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGR1, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGR2, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGR3, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGR4, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGR5, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGR6, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGR7, 16'h0000, WORD); // verify reset |
|
host.wb_cmp(0, XGATE_XGMCTL, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGCHID, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGISPHI, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGISPLO, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGVBR, 16'hfe00, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_7, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_6, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_5, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_4, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_3, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_2, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_1, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGIF_0, 16'h0001, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGSWT, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGSEM, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGCCR, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGPC, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGR1, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGR2, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGR3, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGR4, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGR5, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGR6, 16'h0000, WORD); // verify reset |
host.wb_cmp(0, XGATE_XGR7, 16'h0000, WORD); // verify reset |
|
/* |
parameter XGMCTL_XGDBGM = 15'h2000; |
parameter XGMCTL_XGSSM = 15'h1000; |
788,10 → 792,10
parameter XGMCTL_XGIEM = 15'h0100; |
|
parameter XGMCTL_XGDBG = 15'h0020; |
parameter XGMCTL_XGSS = 15'h0010; |
parameter XGMCTL_XGSS = 15'h0010; |
parameter XGMCTL_XGBRKIE = 15'h0004; |
parameter XGMCTL_XGSWEIF = 15'h0002; |
parameter XGMCTL_XGIE = 15'h0001; |
parameter XGMCTL_XGIE = 15'h0001; |
*/ |
// Test bits in the Xgate Control Register (XGMCTL) |
data_xgmctl = XGMCTL_XGEM | XGMCTL_XGFRZM | XGMCTL_XGFACTM | XGMCTL_XGFRZ | XGMCTL_XGFACT | XGMCTL_XGE; |
828,10 → 832,10
|
host.wb_write(0, XGATE_XGVBR, 16'hFF55, L_BYTE); |
host.wb_cmp(0, XGATE_XGVBR, 16'hAA54, WORD); |
|
|
host.wb_write(0, XGATE_XGVBR, 16'h55AA, H_BYTE); |
host.wb_cmp(0, XGATE_XGVBR, 16'h5554, WORD); |
|
|
data_xgmctl = XGMCTL_XGEM | XGMCTL_XGE; |
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // |
data_xgmctl = XGMCTL_XGE; |
991,10 → 995,10
begin |
repeat(1) @(posedge mstr_test_clk); |
sync_reset = 1'b1; // Make the sync reset 1 clock cycle long |
#2; // move the async reset away from the clock edge |
rstn = 1'b0; // assert async reset |
#5; // Keep the async reset pulse with less than a clock cycle |
rstn = 1'b1; // negate async reset |
#2; // move the async reset away from the clock edge |
rstn = 1'b0; // assert async reset |
#5; // Keep the async reset pulse with less than a clock cycle |
rstn = 1'b1; // negate async reset |
repeat(1) @(posedge mstr_test_clk); |
sync_reset = 1'b0; |
|
1036,21 → 1040,21
begin |
$display("Clearing Channel interrupt flag #%d", chan_val); |
if (0 < chan_val < 16) |
host.wb_write(1, XGATE_XGIF_0, 16'hffff, WORD); |
host.wb_write(1, XGATE_XGIF_0, 16'hffff, WORD); |
if (15 < chan_val < 32) |
host.wb_write(1, XGATE_XGIF_1, 16'hffff, WORD); |
host.wb_write(1, XGATE_XGIF_1, 16'hffff, WORD); |
if (31 < chan_val < 48) |
host.wb_write(1, XGATE_XGIF_2, 16'hffff, WORD); |
host.wb_write(1, XGATE_XGIF_2, 16'hffff, WORD); |
if (47 < chan_val < 64) |
host.wb_write(1, XGATE_XGIF_3, 16'hffff, WORD); |
host.wb_write(1, XGATE_XGIF_3, 16'hffff, WORD); |
if (63 < chan_val < 80) |
host.wb_write(1, XGATE_XGIF_4, 16'hffff, WORD); |
host.wb_write(1, XGATE_XGIF_4, 16'hffff, WORD); |
if (79 < chan_val < 96) |
host.wb_write(1, XGATE_XGIF_5, 16'hffff, WORD); |
host.wb_write(1, XGATE_XGIF_5, 16'hffff, WORD); |
if (95 < chan_val < 112) |
host.wb_write(1, XGATE_XGIF_6, 16'hffff, WORD); |
host.wb_write(1, XGATE_XGIF_6, 16'hffff, WORD); |
if (111 < chan_val < 128) |
host.wb_write(1, XGATE_XGIF_7, 16'hffff, WORD); |
host.wb_write(1, XGATE_XGIF_7, 16'hffff, WORD); |
|
channel_req[chan_val] = 1'b0; // |
repeat(1) @(posedge mstr_test_clk); |
1076,7 → 1080,7
task read_ram_cmp; |
input [15:0] address; |
input [15:0] value; |
reg [15:0] q; |
reg [15:0] q; |
begin |
|
// BIGENDIAN |
1084,8 → 1088,8
// "X" compares don't work, "X" in value or q always match |
if (value != q) |
begin |
error_count = error_count + 1; |
$display("RAM Data compare error at address %h. Received %h, expected %h at time %t", address, q, value, $time); |
error_count = error_count + 1; |
$display("RAM Data compare error at address %h. Received %h, expected %h at time %t", address, q, value, $time); |
end |
end |
endtask |
1135,8 → 1139,8
//////////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
module bus_arbitration #(parameter dwidth = 16, |
parameter awidth = 24, |
module bus_arbitration #(parameter dwidth = 16, |
parameter awidth = 24, |
parameter ram_base = 0, |
parameter ram_size = 16'hffff, |
parameter slv1_base = 0, |
1145,83 → 1149,83
parameter slv2_size = 1) |
( |
// System bus I/O |
output reg sys_cyc, |
output reg sys_stb, |
output reg sys_we, |
output reg sys_cyc, |
output reg sys_stb, |
output reg sys_we, |
output reg [dwidth/8 -1:0] sys_sel, |
output reg [awidth -1:0] sys_adr, |
output reg [dwidth -1:0] sys_dout, |
output [dwidth -1:0] sys_din, |
|
|
// Host bus I/O |
output host_ack, |
output host_ack, |
output [dwidth -1:0] host_dout, |
input host_cyc, |
input host_stb, |
input host_we, |
input [dwidth/8 -1:0] host_sel, |
input [awidth -1:0] host_adr, |
input [dwidth -1:0] host_din, |
|
input host_cyc, |
input host_stb, |
input host_we, |
input [dwidth/8 -1:0] host_sel, |
input [awidth -1:0] host_adr, |
input [dwidth -1:0] host_din, |
|
// Alternate Bus Master #1 Bus I/O |
output alt1_ack, |
output alt1_ack, |
output [dwidth -1:0] alt1_dout, |
input alt1_cyc, |
input alt1_stb, |
input alt1_we, |
input [dwidth/8 -1:0] alt1_sel, |
input [awidth -1:0] alt1_adr, |
input [dwidth -1:0] alt1_din, |
|
input alt1_cyc, |
input alt1_stb, |
input alt1_we, |
input [dwidth/8 -1:0] alt1_sel, |
input [awidth -1:0] alt1_adr, |
input [dwidth -1:0] alt1_din, |
|
// System RAM memory signals |
output ram_sel, |
input [dwidth -1:0] ram_dout, |
output ram_sel, |
input [dwidth -1:0] ram_dout, |
|
// Slave #1 Bus I/O |
output slv1_stb, |
input slv1_ack, |
input [dwidth -1:0] slv1_din, |
|
output slv1_stb, |
input slv1_ack, |
input [dwidth -1:0] slv1_din, |
|
// Slave #2 Bus I/O |
output slv2_stb, |
input slv2_ack, |
input [dwidth -1:0] slv2_din, |
|
output slv2_stb, |
input slv2_ack, |
input [dwidth -1:0] slv2_din, |
|
// Miscellaneous |
input host_clk, |
input risc_clk, |
input rst, // No Connect |
input err, // No Connect |
input rty // No Connect |
input host_clk, |
input risc_clk, |
input rst, // No Connect |
input err, // No Connect |
input rty // No Connect |
); |
|
|
// States for bus arbitration |
parameter [1:0] BUS_IDLE = 2'b00, |
HOST_OWNS = 2'b10, |
RISC_OWNS = 2'b11; |
|
parameter max_bus_hold = 5; // Max number of cycles any bus master can hold the system bus |
HOST_OWNS = 2'b10, |
RISC_OWNS = 2'b11; |
|
parameter max_bus_hold = 5; // Max number of cycles any bus master can hold the system bus |
parameter ram_wait_states = 0; // Number between 0 and 15 |
////////////////////////////////////////////////////////////////////////////// |
// |
// Local Wires and Registers |
// |
wire ram_ack; // |
wire any_ack; // |
reg host_wait; // Host bus in wait state, Hold the bus till the transaction complets |
wire ram_ack; // |
wire any_ack; // |
reg host_wait; // Host bus in wait state, Hold the bus till the transaction complets |
reg [3:0] host_cycle_cnt; // Used to count the cycle the host and break the lock if the risc needs access |
|
wire risc_lock; // RISC has the slave bus |
reg risc_wait; // RISC bus in wait state, Hold the bus till the transaction complets |
|
wire risc_lock; // RISC has the slave bus |
reg risc_wait; // RISC bus in wait state, Hold the bus till the transaction complets |
reg [3:0] risc_cycle_cnt; // Used to count the cycle the risc and break the lock if the host needs access |
|
|
reg [1:0] owner_state; |
reg [1:0] owner_ns; |
|
wire host_timeout; |
wire risc_timeout; |
|
wire ram_ack_dly; // Delayed bus ack to simulate bus wait states |
wire host_timeout; |
wire risc_timeout; |
|
wire ram_ack_dly; // Delayed bus ack to simulate bus wait states |
reg [3:0] ack_dly_cnt; // Counter to delay bus ack to master modules |
|
|
1231,7 → 1235,7
owner_state <= BUS_IDLE; |
else |
owner_state <= owner_ns; |
|
|
// |
always @* |
case (owner_state) |
1259,7 → 1263,7
default : owner_ns = BUS_IDLE; |
endcase |
|
|
|
assign host_timeout = (owner_state == HOST_OWNS) && (host_cycle_cnt > max_bus_hold) && any_ack; |
assign risc_timeout = (owner_state == RISC_OWNS) && (risc_cycle_cnt > max_bus_hold) && any_ack; |
|
1269,7 → 1273,7
host_cycle_cnt <= 0; |
else if ((owner_state != HOST_OWNS) || !alt1_cyc) |
host_cycle_cnt <= 0; |
else if (&host_cycle_cnt && !host_timeout) // Don't allow rollover |
else if (&host_cycle_cnt && !host_timeout) // Don't allow rollover |
host_cycle_cnt <= host_cycle_cnt; |
else if ((owner_state == HOST_OWNS) && alt1_cyc) |
host_cycle_cnt <= host_cycle_cnt + 1'b1; |
1280,12 → 1284,12
risc_cycle_cnt <= 0; |
else if ((owner_state != RISC_OWNS) || !host_cyc) |
risc_cycle_cnt <= 0; |
else if (&risc_cycle_cnt && !risc_timeout) // Don't allow rollover |
else if (&risc_cycle_cnt && !risc_timeout) // Don't allow rollover |
risc_cycle_cnt <= risc_cycle_cnt; |
else if ((owner_state == RISC_OWNS) && host_cyc) |
risc_cycle_cnt <= risc_cycle_cnt + 1'b1; |
|
// Aribartration Logic for System Bus access |
// Aribartration Logic for System Bus access |
assign any_ack = slv1_ack || slv2_ack || ram_ack; |
assign host_ack = (owner_state == HOST_OWNS) && any_ack && host_cyc; |
assign alt1_ack = (owner_state == RISC_OWNS) && any_ack && alt1_cyc; |
1294,12 → 1298,12
// Address decoding for different Slave module instances |
assign slv1_stb = sys_stb && (sys_adr >= slv1_base) && (sys_adr < (slv1_base + slv1_size)); |
assign slv2_stb = sys_stb && (sys_adr >= slv2_base) && (sys_adr < (slv2_base + slv2_size)); |
|
|
// Address decoding for Testbench access to RAM |
assign ram_sel = sys_cyc && sys_stb && !(slv1_stb || slv2_stb) && |
(sys_adr >= ram_base) && |
(sys_adr >= ram_base) && |
(sys_adr < (ram_base + ram_size)); |
|
|
// Throw in some wait states from the memory |
always @(posedge host_clk) |
if ((ack_dly_cnt == ram_wait_states) || !ram_sel) |
1313,8 → 1317,8
|
// Create the System Read Data Bus from the Slave output data buses |
assign sys_din = ({dwidth{slv1_stb}} & slv1_din) | |
({dwidth{slv2_stb}} & slv2_din) | |
({dwidth{ram_sel}} & ram_dout); |
({dwidth{slv2_stb}} & slv2_din) | |
({dwidth{ram_sel}} & ram_dout); |
|
// Mux for System Bus access |
always @* |
1321,39 → 1325,39
case (owner_state) |
BUS_IDLE : |
begin |
sys_cyc = 0; |
sys_stb = 0; |
sys_we = 0; |
sys_sel = 0; |
sys_adr = 0; |
sys_dout = 0; |
sys_cyc = 0; |
sys_stb = 0; |
sys_we = 0; |
sys_sel = 0; |
sys_adr = 0; |
sys_dout = 0; |
end |
HOST_OWNS : |
begin |
sys_cyc = host_cyc; |
sys_stb = host_stb; |
sys_we = host_we; |
sys_sel = host_sel; |
sys_adr = host_adr; |
sys_dout = host_din; |
sys_cyc = host_cyc; |
sys_stb = host_stb; |
sys_we = host_we; |
sys_sel = host_sel; |
sys_adr = host_adr; |
sys_dout = host_din; |
end |
RISC_OWNS : |
begin |
sys_cyc = alt1_cyc; |
sys_stb = alt1_stb; |
sys_we = alt1_we; |
sys_sel = alt1_sel; |
sys_adr = alt1_adr; |
sys_dout = alt1_din; |
sys_cyc = alt1_cyc; |
sys_stb = alt1_stb; |
sys_we = alt1_we; |
sys_sel = alt1_sel; |
sys_adr = alt1_adr; |
sys_dout = alt1_din; |
end |
default : |
begin |
sys_cyc = 0; |
sys_stb = 0; |
sys_we = 0; |
sys_sel = 0; |
sys_adr = 0; |
sys_dout = 0; |
sys_cyc = 0; |
sys_stb = 0; |
sys_we = 0; |
sys_sel = 0; |
sys_adr = 0; |
sys_dout = 0; |
end |
endcase |
|
1363,32 → 1367,32
//////////////////////////////////////////////////////////////////////////////// |
//////////////////////////////////////////////////////////////////////////////// |
module tb_slave #(parameter SINGLE_CYCLE = 1'b0, // No bus wait state added |
parameter DWIDTH = 16) // Data bus width |
parameter DWIDTH = 16) // Data bus width |
( |
// Wishbone Signals |
output [DWIDTH-1:0] wb_dat_o, // databus output |
output wb_ack_o, // bus cycle acknowledge output |
input wb_clk_i, // master clock input |
input wb_rst_i, // synchronous active high reset |
input arst_i, // asynchronous reset |
input [2:0] wb_adr_i, // lower address bits |
input [DWIDTH-1:0] wb_dat_i, // databus input |
input wb_we_i, // write enable input |
input wb_stb_i, // stobe/core select signal |
input wb_cyc_i, // valid bus cycle input |
input [1:0] wb_sel_i, // Select byte in word bus transaction |
// PIT IO Signals |
output reg error_pulse, // Error detected output pulse |
output reg ack_pulse, // Thread ack output pulse |
input [19:0] vector |
output [DWIDTH-1:0] wb_dat_o, // databus output |
output wb_ack_o, // bus cycle acknowledge output |
input wb_clk_i, // master clock input |
input wb_rst_i, // synchronous active high reset |
input arst_i, // asynchronous reset |
input [2:0] wb_adr_i, // lower address bits |
input [DWIDTH-1:0] wb_dat_i, // databus input |
input wb_we_i, // write enable input |
input wb_stb_i, // stobe/core select signal |
input wb_cyc_i, // valid bus cycle input |
input [1:0] wb_sel_i, // Select byte in word bus transaction |
// Slave unique IO Signals |
output reg error_pulse, // Error detected output pulse |
output reg ack_pulse, // Thread ack output pulse |
input [19:0] vector |
); |
|
wire async_rst_b; // Asyncronous reset |
wire sync_reset; // Syncronous reset |
|
|
wire async_rst_b; // Asyncronous reset |
wire sync_reset; // Syncronous reset |
|
// Wishbone Bus interface |
// registers |
reg bus_wait_state; // Holdoff wb_ack_o for one clock to add wait state |
reg bus_wait_state; // Holdoff wb_ack_o for one clock to add wait state |
reg [DWIDTH-1:0] rd_data_mux; // Pseudo Register, WISHBONE Read Data Mux |
reg [DWIDTH-1:0] rd_data_reg; // Latch for WISHBONE Read Data |
|
1401,9 → 1405,9
event channel_err_wrt; |
|
// Wires |
wire module_sel; // This module is selected for bus transaction |
wire wb_wacc; // WISHBONE Write Strobe |
wire wb_racc; // WISHBONE Read Access (Clock gating signal) |
wire module_sel; // This module is selected for bus transaction |
wire wb_wacc; // WISHBONE Write Strobe |
wire wb_racc; // WISHBONE Read Access (Clock gating signal) |
|
// |
// module body |
1423,15 → 1427,15
// Accesses in back to back clock cycles are not possable. |
always @(posedge wb_clk_i or negedge arst_i) |
if (!arst_i) |
bus_wait_state <= 1'b0; |
bus_wait_state <= 1'b0; |
else if (wb_rst_i) |
bus_wait_state <= 1'b0; |
bus_wait_state <= 1'b0; |
else |
bus_wait_state <= module_sel && !bus_wait_state; |
bus_wait_state <= module_sel && !bus_wait_state; |
|
// assign data read bus -- DAT_O |
always @(posedge wb_clk_i) |
if ( wb_racc ) // Clock gate for power saving |
if ( wb_racc ) // Clock gate for power saving |
rd_data_reg <= rd_data_mux; |
|
// WISHBONE Read Data Mux |
1447,34 → 1451,34
always @(posedge wb_clk_i or negedge arst_i) |
begin |
if (!arst_i) |
begin |
check_point_reg <= 0; |
channel_ack_reg <= 0; |
channel_err_reg <= 0; |
ack_pulse <= 0; |
error_pulse <= 0; |
end |
begin |
check_point_reg <= 0; |
channel_ack_reg <= 0; |
channel_err_reg <= 0; |
ack_pulse <= 0; |
error_pulse <= 0; |
end |
else if (wb_wacc) |
case (wb_adr_i) // synopsys parallel_case |
3'b000 : |
begin |
check_point_reg[ 7:0] <= wb_sel_i[0] ? wb_dat_i[ 7:0] : check_point_reg[ 7:0]; |
check_point_reg[15:8] <= wb_sel_i[1] ? wb_dat_i[15:8] : check_point_reg[15:8]; |
-> check_point_wrt; |
check_point_reg[ 7:0] <= wb_sel_i[0] ? wb_dat_i[ 7:0] : check_point_reg[ 7:0]; |
check_point_reg[15:8] <= wb_sel_i[1] ? wb_dat_i[15:8] : check_point_reg[15:8]; |
-> check_point_wrt; |
end |
3'b001 : |
begin |
channel_ack_reg[ 7:0] <= wb_sel_i[0] ? wb_dat_i[ 7:0] : channel_ack_reg[ 7:0]; |
channel_ack_reg[15:8] <= wb_sel_i[1] ? wb_dat_i[15:8] : channel_ack_reg[15:8]; |
channel_ack_reg[ 7:0] <= wb_sel_i[0] ? wb_dat_i[ 7:0] : channel_ack_reg[ 7:0]; |
channel_ack_reg[15:8] <= wb_sel_i[1] ? wb_dat_i[15:8] : channel_ack_reg[15:8]; |
ack_pulse <= 1; |
-> channel_ack_wrt; |
-> channel_ack_wrt; |
end |
3'b010 : |
begin |
channel_err_reg[ 7:0] <= wb_sel_i[0] ? wb_dat_i[ 7:0] : channel_err_reg[ 7:0]; |
channel_err_reg[15:8] <= wb_sel_i[1] ? wb_dat_i[15:8] : channel_err_reg[15:8]; |
channel_err_reg[ 7:0] <= wb_sel_i[0] ? wb_dat_i[ 7:0] : channel_err_reg[ 7:0]; |
channel_err_reg[15:8] <= wb_sel_i[1] ? wb_dat_i[15:8] : channel_err_reg[15:8]; |
error_pulse <= 1'b1; |
-> channel_err_wrt; |
-> channel_err_wrt; |
end |
3'b011 : |
begin |
1485,7 → 1489,7
begin |
ack_pulse <= 0; |
error_pulse <= 1'b0; |
end |
end |
end |
|
always @check_point_wrt |
1497,7 → 1501,7
always @channel_err_wrt |
begin |
#1; |
$display("\n ------ !!!!! Software Checkpoint Error #%d -- at vector=%d\n -------", channel_err_reg, vector); |
$display("\n ------ !!!!! Software Checkpoint Error #%d -- at vector=%d\n -------", channel_err_reg, vector); |
end |
|
|