OpenCores
URL https://opencores.org/ocsvn/xgate/xgate/trunk

Subversion Repositories xgate

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /xgate/trunk
    from Rev 53 to Rev 54
    Reverse comparison

Rev 53 → Rev 54

/bench/verilog/tst_bench_top.v
45,7 → 45,7
 
parameter MAX_CHANNEL = 127; // Max XGATE Interrupt Channel Number
parameter STOP_ON_ERROR = 1'b0;
parameter MAX_VECTOR = 2300;
parameter MAX_VECTOR = 3000;
 
parameter L_BYTE = 2'b01;
parameter H_BYTE = 2'b10;
53,7 → 53,7
 
 
// Name Address Locations
parameter XGATE_BASE = 32'b0;
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;
103,7 → 103,7
parameter CHANNEL_ACK = CHECK_POINT + 2;
parameter CHANNEL_ERR = CHECK_POINT + 4;
parameter SYS_RAM_BASE = 32'h0002_0000;
parameter SYS_RAM_BASE = 24'h0000_0000;
 
//
// wires && regs
114,12 → 114,6
reg [ 7:0] test_num;
reg [15:0] q, qq;
reg [ 7:0] check_point_reg;
reg [ 7:0] channel_ack_reg;
reg [ 7:0] channel_err_reg;
event check_point_wrt;
event channel_ack_wrt;
event channel_err_wrt;
 
reg rstn;
reg sync_reset;
129,11 → 123,9
reg debug_mode;
reg scantestmode;
 
reg wbm_ack_i;
wire [15:0] dat_i;
wire ack;
 
wire [15:0] dat_i, dat1_i, dat2_i, dat3_i;
wire ack, ack_2, ack_3, ack_4;
 
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
148,7 → 140,6
reg mem_wait_state_enable;
 
wire [15:0] tb_ram_out;
wire [31:0] sys_addr;
 
// Registers used to mirror internal registers
reg [15:0] data_xgmctl;
161,8 → 152,9
wire sys_stb;
wire sys_we;
wire [ 1:0] sys_sel;
wire [31:0] sys_adr;
wire [23:0] sys_adr;
wire [15:0] sys_dout;
wire [15:0] sys_din;
wire host_ack;
wire [15:0] host_dout;
170,7 → 162,7
wire host_stb;
wire host_we;
wire [ 1:0] host_sel;
wire [31:0] host_adr;
wire [23:0] host_adr;
wire [15:0] host_din;
wire xgate_ack;
187,7 → 179,7
wire [15:0] xgate_s_dout;
wire slv2_stb;
wire ram_ack;
wire ram_sel;
wire [15:0] ram_dout;
 
// initial values and testbench setup
201,11 → 193,7
wait_mode = 0;
debug_mode = 0;
scantestmode = 0;
check_point_reg = 0;
channel_ack_reg = 0;
channel_err_reg = 0;
error_count = 0;
wbm_ack_i = 1;
mem_wait_state_enable = 0;
// channel_req = 0;
 
245,51 → 233,9
error_count <= error_count + 1;
end
 
 
// Throw in some wait states from the memory
always @(posedge mstr_test_clk)
if (((vector % 5) == 0) && (xgate.risc.load_next_inst || xgate.risc.data_access))
// if ((vector % 5) == 0)
wbm_ack_i <= 1'b1;
else
wbm_ack_i <= 1'b1;
 
// Special Memory Mapped Testbench Registers
always @(posedge mstr_test_clk or negedge rstn)
always @(posedge error_pulse) //channel_ack_wrt
begin
if (!rstn)
begin
check_point_reg <= 0;
channel_ack_reg <= 0;
channel_err_reg <= 0;
end
if (wbm_sel_o[0] && wbm_ack_i && (wbm_adr_o == CHECK_POINT))
begin
check_point_reg <= wbm_dat_o[7:0];
#1;
-> check_point_wrt;
end
if (wbm_sel_o[0] && wbm_ack_i && (wbm_adr_o == CHANNEL_ACK))
begin
channel_ack_reg <= wbm_dat_o[7:0];
#1;
-> channel_ack_wrt;
end
if (wbm_sel_o[0] && wbm_ack_i && (wbm_adr_o == CHANNEL_ERR))
begin
channel_err_reg <= wbm_dat_o[7:0];
#1;
-> channel_err_wrt;
end
end
 
always @check_point_wrt
$display("\nSoftware Checkpoint #%h -- at vector=%d\n", check_point_reg, vector);
 
always @channel_err_wrt
begin
$display("\n ------ !!!!! Software Checkpoint Error #%d -- at vector=%d\n -------", channel_err_reg, vector);
#1;
error_count = error_count + 1;
if (STOP_ON_ERROR == 1'b1)
wrap_up;
296,35 → 242,11
end
 
wire [ 6:0] current_active_channel = xgate.risc.xgchid;
always @channel_ack_wrt
always @(posedge ack_pulse) //channel_ack_wrt
clear_channel(current_active_channel);
 
// Address decoding for different XGATE module instances
wire stb0 = host_stb && ~host_adr[6] && ~host_adr[5] && ~|host_adr[31:16];
wire stb1 = host_stb && ~host_adr[6] && host_adr[5] && ~|host_adr[31:16];
wire stb2 = host_stb && host_adr[6] && ~host_adr[5] && ~|host_adr[31:16];
wire stb3 = host_stb && host_adr[6] && host_adr[5] && ~|host_adr[31:16];
assign dat1_i = 16'h0000;
assign dat2_i = 16'h0000;
assign dat3_i = 16'h0000;
assign ack_2 = 1'b0;
assign ack_3 = 1'b0;
assign ack_4 = 1'b0;
 
// Create the Read Data Bus
assign dat_i = ({16{stb0}} & xgate_s_dout) |
({16{stb1}} & dat1_i) |
({16{stb2}} & dat2_i) |
({16{stb3}} & {8'b0, dat3_i[7:0]});
 
assign ack = xgate_s_ack || ack_2 || ack_3 || ack_4;
 
// Aribartration Logic for Testbench RAM access
assign sys_addr = 1'b1 ? {16'b0, wbm_adr_o} : host_adr;
 
// Testbench RAM for Xgate program storage and Load/Store instruction tests
ram p_ram
(
331,16 → 253,16
// Outputs
.ram_out( ram_dout ),
// inputs
.address( sys_addr[15:0] ), // sys_addr sys_adr
.address( sys_adr[15:0] ),
.ram_in( sys_dout ),
.we( sys_we ),
.ce( 1'b1 ),
.ce( ram_sel ),
.stb( mstr_test_clk ),
.sel( sys_sel ) // wbm_sel_o sys_sel
.sel( sys_sel )
);
 
// hookup wishbone master model
wb_master_model #(.dwidth(16), .awidth(32))
wb_master_model #(.dwidth(16), .awidth(24))
host(
// Outputs
.cyc( host_cyc ),
350,7 → 272,7
.adr( host_adr ),
.dout( host_dout ),
// inputs
.din(host_din),
.din(sys_din),
.clk(mstr_test_clk),
.ack(host_ack),
.rst(rstn),
359,7 → 281,13
);
 
bus_arbitration #(.dwidth(16),
.awidth(32))
.awidth(24),
.ram_base(0),
.ram_size(17'h10000),
.slv1_base(XGATE_BASE),
.slv1_size(64),
.slv2_base(CHECK_POINT),
.slv2_size(8))
arb(
// System bus I/O
.sys_cyc( sys_cyc ),
368,6 → 296,7
.sys_sel( sys_sel ),
.sys_adr( sys_adr ),
.sys_dout( sys_dout ),
.sys_din( sys_din ),
// Host bus I/O
.host_ack( host_ack ),
.host_dout( host_din ),
379,13 → 308,15
.host_din( host_dout ),
// Alternate Bus Master #1 Bus I/O
.alt1_ack( xgate_ack ),
.alt1_dout( xgate_din ),
.alt1_cyc( wbm_cyc_o ),
.alt1_stb( wbm_stb_o ),
.alt1_we( wbm_we_o ),
.alt1_sel( wbm_sel_o ),
.alt1_adr( {16'h0001, wbm_adr_o} ),
.alt1_adr( {8'h00, wbm_adr_o} ),
.alt1_din( wbm_dat_o ),
// RAM
.ram_sel( ram_sel ),
.ram_dout( ram_dout ),
// Slave #1 Bus I/O
.slv1_stb( xgate_s_stb ),
.slv1_ack( xgate_s_ack ),
392,7 → 323,7
.slv1_din( xgate_s_dout ),
// Slave #2 Bus I/O
.slv2_stb( slv2_stb ),
.slv2_ack( wbm_ack_i ),
.slv2_ack( test_reg_ack ),
.slv2_din( ram_dout ),
// Miscellaneous
.host_clk( mstr_test_clk ),
401,9 → 332,9
.err( 1'b0 ), // No Connect
.rty( 1'b0 ) // No Connect
);
// hookup XGATE core - Parameters take all default values
// Async Reset, 16 bit Bus, 8 bit Granularity
xgate_top #(.SINGLE_CYCLE(1'b1),
xgate_top #(.SINGLE_CYCLE(1'b0),
.MAX_CHANNEL(MAX_CHANNEL)) // Max XGATE Interrupt Channel Number
xgate(
// Wishbone slave interface
418,6 → 349,7
.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 ),
426,8 → 358,8
.wbm_cyc_o( wbm_cyc_o ),
.wbm_sel_o( wbm_sel_o ),
.wbm_adr_o( wbm_adr_o ),
.wbm_dat_i( ram_dout ),
.wbm_ack_i( wbm_ack_i ),
.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
437,13 → 369,34
.scantestmode( scantestmode )
);
 
tb_slave #(.DWIDTH(16),
.SINGLE_CYCLE(1'b1))
tb_slave_regs(
// wishbone interface
.wb_clk_i( mstr_test_clk ),
.wb_rst_i( 1'b0 ),
.arst_i( rstn ),
.wb_adr_i( sys_adr[3:1] ),
.wb_dat_i( sys_dout ),
.wb_dat_o(),
.wb_we_i( sys_we ),
.wb_stb_i( slv2_stb ),
.wb_cyc_i( sys_cyc ),
.wb_sel_i( sys_sel ),
.wb_ack_o( test_reg_ack ),
 
.ack_pulse( ack_pulse ),
.error_pulse( error_pulse ),
.vector( vector )
);
 
 
 
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
 
// Test Program
// Main Test Program
initial
begin
$display("\nstatus at time: %t Testbench started", $time);
475,14 → 428,10
 
reg_test_16;
 
// host_ram;
//host_ram;
 
// End testing
wrap_up;
 
 
repeat(10) @(posedge mstr_test_clk);
 
wrap_up;
end
 
////////////////////////////////////////////////////////////////////////////////
602,7 → 551,7
while (qq == q) // Look for change in R3 register
begin
host.wb_write(0, XGATE_XGMCTL, data_xgmctl, WORD); // Do a Single Step
repeat(5) @(posedge mstr_test_clk);
repeat(7) @(posedge mstr_test_clk);
host.wb_read(1, XGATE_XGR3, q, WORD);
end
if (q != (qq+1))
612,16 → 561,16
end
 
 
host.wb_write(1, XGATE_XGPC, 16'h2094, WORD); // Write to PC to force exit from infinate loop
repeat(5) @(posedge mstr_test_clk);
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)
repeat(5) @(posedge mstr_test_clk);
repeat(10) @(posedge mstr_test_clk);
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)
repeat(5) @(posedge mstr_test_clk);
repeat(10) @(posedge mstr_test_clk);
host.wb_cmp(0, XGATE_XGR4, 16'h0003, WORD); // See Program code.(R4 <= R4 + 1)
 
data_xgmctl = XGMCTL_XGDBGM;
1186,16 → 1135,23
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
module bus_arbitration #(parameter dwidth = 32,
parameter awidth = 32)
module bus_arbitration #(parameter dwidth = 16,
parameter awidth = 24,
parameter ram_base = 0,
parameter ram_size = 16'hffff,
parameter slv1_base = 0,
parameter slv1_size = 1,
parameter slv2_base = 0,
parameter slv2_size = 1)
(
// System bus I/O
output sys_cyc,
output sys_stb,
output sys_we,
output [dwidth/8 -1:0] sys_sel,
output [awidth -1:0] sys_adr,
output [dwidth -1:0] sys_dout,
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,
1217,6 → 1173,10
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,
 
// Slave #1 Bus I/O
output slv1_stb,
input slv1_ack,
1235,82 → 1195,309
input rty // No Connect
);
// Debug states for change CHID
parameter [1:0] BUS_IDLE = 2'b00,
HOST_OWNS = 2'b10,
RISC_OWNS = 2'b11;
//////////////////////////////////////////////////////////////////////////////
//
// Local Wires and Registers
//
wire host_lock; // Host has the slave bus
reg host_lock_ext; // Host lock extend, 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_lock_ext; // RISC lock extend, Hold the bus till the transaction complets
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;
 
// Aribartration Logic for System Bus access
reg wbm_ack_i;
 
 
//
always @(posedge host_clk or negedge rst)
if (!rst)
host_lock_ext <= 1'b0;
owner_state <= BUS_IDLE;
else
host_lock_ext <= host_cyc && !host_ack;
owner_state <= owner_ns;
//
always @*
case (owner_state)
BUS_IDLE :
begin
if (host_cyc)
owner_ns = HOST_OWNS;
else if (alt1_cyc)
owner_ns = RISC_OWNS;
end
HOST_OWNS :
begin
if (!host_cyc && !alt1_cyc)
owner_ns = BUS_IDLE;
else if (alt1_cyc && (!host_cyc || host_timeout))
owner_ns = RISC_OWNS;
end
RISC_OWNS :
begin
if (!host_cyc && !alt1_cyc)
owner_ns = BUS_IDLE;
else if (host_cyc && (!alt1_cyc || risc_timeout))
owner_ns = HOST_OWNS;
end
default : owner_ns = BUS_IDLE;
endcase
 
always @(posedge host_clk or negedge rst)
if (!rst)
risc_lock_ext <= 1'b0;
/*
// Throw in some wait states from the memory
always @(posedge mstr_test_clk)
if (((vector % 5) == 0) && (xgate.risc.load_next_inst || xgate.risc.data_access))
// if ((vector % 5) == 0)
wbm_ack_i <= 1'b1;
else
risc_lock_ext <= alt1_cyc && !alt1_ack;
wbm_ack_i <= 1'b1;
*/
 
// Start counting cycles the host has the bus if the risc is also requesting the bus
assign host_timeout = (owner_state == HOST_OWNS) && (host_cycle_cnt > 5) && any_ack;
assign risc_timeout = (owner_state == RISC_OWNS) && (risc_cycle_cnt > 5) && any_ack;
 
// Start counting cycles that the host has the bus, if the risc is also requesting the bus
always @(posedge host_clk or negedge rst)
if (!rst)
host_cycle_cnt <= 0;
else
host_cycle_cnt <= (host_lock && alt1_cyc) ? (host_cycle_cnt + 1'b1) : 0;
else if ((owner_state != HOST_OWNS) || !alt1_cyc)
host_cycle_cnt <= 0;
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;
 
// Start counting cycles the risc has the bus if the host is also requesting the bus
// Start counting cycles that the risc has the bus, if the host is also requesting the bus
always @(posedge host_clk or negedge rst)
if (!rst)
risc_cycle_cnt <= 0;
else
risc_cycle_cnt <= (risc_lock && host_cyc) ? (risc_cycle_cnt + 1'b1) : 0;
else if ((owner_state != RISC_OWNS) || !host_cyc)
risc_cycle_cnt <= 0;
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;
 
assign host_lock = ((host_cyc && !risc_lock_ext) || host_lock_ext) && (host_cycle_cnt < 5);
assign risc_lock = !host_lock;
wire alt1_master = !host_lock;
// 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;
 
// Address decoding for different XGATE module instances
assign slv1_stb = sys_stb && ~sys_adr[7] && ~sys_adr[6] && ~|sys_adr[31:8];
wire slv3_stb = sys_stb && ~sys_adr[7] && sys_adr[6] && ~|sys_adr[31:8];
wire slv4_stb = sys_stb && sys_adr[7] && ~sys_adr[6] && ~|sys_adr[31:8];
wire slv5_stb = sys_stb && sys_adr[7] && sys_adr[6] && ~|sys_adr[31:8];
 
// 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 slv2_stb = alt1_master ? (alt1_stb && sys_adr[16] && ~|sys_adr[31:17]) :
(host_stb && ~sys_adr[16] && sys_adr[17] && ~|sys_adr[31:18]);
assign ram_sel = sys_cyc && sys_stb && !(slv1_stb || slv2_stb) &&
(sys_adr >= ram_base) &&
(sys_adr < (ram_base + ram_size));
assign ram_ack = ram_sel;
 
 
// Create the Host Read Data Bus
assign host_dout = ({dwidth{slv1_stb}} & slv1_din) |
({dwidth{slv2_stb}} & slv2_din);
// 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);
 
// Create the Alternate #1 Read Data Bus
assign alt1_dout = ({dwidth{slv1_stb}} & slv1_din) |
({dwidth{slv2_stb}} & slv2_din);
// Mux for System Bus access
always @*
case (owner_state)
BUS_IDLE :
begin
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;
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;
end
default :
begin
sys_cyc = 0;
sys_stb = 0;
sys_we = 0;
sys_sel = 0;
sys_adr = 0;
sys_dout = 0;
end
endcase
 
assign host_ack = host_lock && (slv1_ack || slv2_ack);
assign alt1_ack = risc_lock && (slv1_ack || slv2_ack);
endmodule // bus_arbitration
 
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
module tb_slave #(parameter SINGLE_CYCLE = 1'b0, // No bus wait state added
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
);
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 [DWIDTH-1:0] rd_data_mux; // Pseudo Register, WISHBONE Read Data Mux
reg [DWIDTH-1:0] rd_data_reg; // Latch for WISHBONE Read Data
 
// Mux for System Bus access
assign sys_cyc = alt1_cyc || host_cyc;
assign sys_stb = alt1_master ? alt1_stb : host_stb;
assign sys_we = alt1_master ? alt1_we : host_we;
assign sys_sel = alt1_master ? alt1_sel : host_sel;
assign sys_adr = alt1_master ? alt1_adr : host_adr;
assign sys_dout = alt1_master ? alt1_din : host_din;
reg [15:0] check_point_reg;
reg [15:0] channel_ack_reg;
reg [15:0] channel_err_reg;
 
endmodule // bus_arbitration
event check_point_wrt;
event channel_ack_wrt;
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)
 
//
// module body
//
 
// generate internal resets
 
 
// generate wishbone signals
assign module_sel = wb_cyc_i && wb_stb_i;
assign wb_wacc = module_sel && wb_we_i && (wb_ack_o || SINGLE_CYCLE);
assign wb_racc = module_sel && !wb_we_i;
assign wb_ack_o = SINGLE_CYCLE ? module_sel : bus_wait_state;
assign wb_dat_o = SINGLE_CYCLE ? rd_data_mux : rd_data_reg;
 
// generate acknowledge output signal, By using register all accesses takes two cycles.
// 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;
else if (wb_rst_i)
bus_wait_state <= 1'b0;
else
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
rd_data_reg <= rd_data_mux;
 
// WISHBONE Read Data Mux
always @*
case (wb_adr_i) // synopsys parallel_case
3'b000: rd_data_mux = check_point_reg;
3'b001: rd_data_mux = channel_ack_reg;
3'b010: rd_data_mux = channel_err_reg;
3'b011: rd_data_mux = 16'b0;
endcase
 
// generate wishbone write register strobes
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
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;
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];
ack_pulse <= 1;
-> 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];
error_pulse <= 1'b1;
-> channel_err_wrt;
end
3'b011 :
begin
end
default: ;
endcase
else
begin
ack_pulse <= 0;
error_pulse <= 1'b0;
end
end
 
always @check_point_wrt
begin
#1;
$display("\nSoftware Checkpoint #%h -- at vector=%d\n", check_point_reg, vector);
end
 
always @channel_err_wrt
begin
#1;
$display("\n ------ !!!!! Software Checkpoint Error #%d -- at vector=%d\n -------", channel_err_reg, vector);
end
 
 
endmodule // tb_slave
 
/bench/verilog/debug_test.v
2,7 → 2,7
@2000 21 46
@2012 56 FF
@201E F2 04 FA 80 F3 FF 53 40 03 00 02 00 F2 00 FA 80 F3 01 53 40 53 42 F4 C3 5C 08 F7 01 00 00 E3 01 01 00 3C 11 E3 40 01 00 E3 60 5B 0C E3 01 18 9C 24 0D 4D 0C E5 01 18 74 24 09 F2 00 FA 80 F3 02
@205E 53 40 03 00 02 00 E3 01 4F 08 3F EF F2 04 FA 80 F3 01 53 40 03 00 02 00 F2 00 FA 80 F3 03 53 40 F3 02 53 42 F3 01 F4 01 F7 03 E3 01 01 00 3F FD 01 00 01 00 E4 60 E4 01 E4 01 18 9C 24 06 F2 00
@205E 53 40 03 00 02 00 E3 01 4F 08 3F EF F2 04 FA 80 F3 01 53 40 03 00 02 00 F2 00 FA 80 F3 03 53 40 F3 02 53 42 F3 01 F4 01 F7 03 E3 01 16 1B 3F FD 01 00 01 00 E4 60 E4 01 E4 01 18 9C 24 06 F2 00
@209E FA 80 F3 04 53 40 03 00 02 00 F2 04 FA 80 F3 02 53 40 03 00 02 00 F2 00 FA 80 F3 05 53 40 F3 03 53 42 F3 01 F4 01 F7 03 00 00 F2 04 FA 80 F3 03 53 40 03 00 02 00 F2 00 FA 80 F3 06 53 40 00 00
@20DE F2 00 FA 80 F3 07 53 40 03 00 02 00 F2 04 FA 80 F3 04 53 40 03 00 02 00 F2 00 FA 80 F3 08 53 40 F3 05 53 42 00 00 F2 00 FA 80 F3 09 53 40 03 00 02 00 F2 04 FA 80 F3 05 53 40 03 00 02 00 00 00
@211E 3C 01 3C 0C F2 00 FA 80 F3 0A 53 40 F3 06 53 42 F2 00 FA 80 F3 0B 53 40 03 00 02 00 F2 04 FA 80 F3 06 53 40 03 00 02 00 07 F7 00 00

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.