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

Subversion Repositories wb_size_bridge

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /wb_size_bridge
    from Rev 3 to Rev 4
    Reverse comparison

Rev 3 → Rev 4

/trunk/tb/test/debug/tb_dut.v
1,152 → 1,175
// --------------------------------------------------------------------
//
// --------------------------------------------------------------------
 
`timescale 1ns/10ps
 
 
module tb_dut(
input tb_clk,
input tb_rst
);
 
 
wire wb_hi_clk = tb_clk;
wire wb_hi_rst = tb_rst;
 
wire [31:0] wb_hi_dat_i, wb_hi_dat_o;
wire [31:0] wb_hi_adr_o;
wire wb_hi_cyc_o, wb_hi_stb_o;
wire wb_hi_we_o;
wire [ 3:0] wb_hi_sel_o;
wire wb_hi_ack_i, wb_hi_err_i, wb_hi_rty_i;
 
wire wb_lo_clk_o;
wire wb_lo_rst_o;
 
wire [15:0] wb_lo_dat_i, wb_lo_dat_o;
wire [31:0] wb_lo_adr_o;
wire wb_lo_cyc_o, wb_lo_stb_o;
wire wb_lo_we_o;
wire [1:0] wb_lo_sel_o;
wire wb_lo_ack_i, wb_lo_err_i, wb_lo_rty_i;
wire lo_byte_if_i;
 
 
// --------------------------------------------------------------------
// wb_hi_master_model
wb_master_model wbm(
.clk(wb_hi_clk),
.rst(wb_hi_rst),
.adr(wb_hi_adr_o),
.din(wb_hi_dat_i),
.dout(wb_hi_dat_o),
.cyc(wb_hi_cyc_o),
.stb(wb_hi_stb_o),
.we(wb_hi_we_o),
.sel(wb_hi_sel_o),
.ack(wb_hi_ack_i),
.err(wb_hi_err_i),
.rty(wb_hi_rty_i)
);
 
 
// --------------------------------------------------------------------
// wb_hi_size_bridge
wb_size_bridge i_wb_size_bridge(
.wb_hi_clk_i(wb_hi_clk),
.wb_hi_rst_i(wb_hi_rst),
.wb_hi_dat_o(wb_hi_dat_i),
.wb_hi_dat_i(wb_hi_dat_o),
.wb_hi_adr_i(wb_hi_adr_o),
.wb_hi_cyc_i(wb_hi_cyc_o),
.wb_hi_we_i(wb_hi_we_o),
.wb_hi_stb_i(wb_hi_stb_o),
.wb_hi_sel_i(wb_hi_sel_o),
.wb_hi_ack_o(wb_hi_ack_i),
.wb_hi_err_o(wb_hi_err_i),
.wb_hi_rty_o(wb_hi_rty_i),
.wb_lo_clk_o(wb_lo_clk_o),
.wb_lo_rst_o(wb_lo_rst_o),
.wb_lo_dat_o(wb_lo_dat_o),
.wb_lo_dat_i(wb_lo_dat_i),
.wb_lo_adr_o(wb_lo_adr_o),
.wb_lo_cyc_o(wb_lo_cyc_o),
.wb_lo_we_o(wb_lo_we_o),
.wb_lo_stb_o(wb_lo_stb_o),
.wb_lo_sel_o(wb_lo_sel_o),
.wb_lo_ack_i(wb_lo_ack_i),
.wb_lo_err_i(wb_lo_err_i),
.wb_lo_rty_i(wb_lo_rty_i),
.lo_byte_if_i(lo_byte_if_i)
);
// --------------------------------------------------------------------
// wb_slave_model
wire slave_08_bit_hit = (wb_lo_adr_o[31:24] == 8'h60) & wb_lo_cyc_o;
wire [15:0] slave_08_bit_dat_o;
wire [15:0] slave_16_bit_dat_o;
assign wb_lo_dat_i[15:0] = slave_08_bit_hit ? slave_08_bit_dat_o : slave_16_bit_dat_o;
wire slave_08_bit_ack_o;
wire slave_08_bit_err_o;
wire slave_08_bit_rty_o;
wire slave_16_bit_ack_o;
wire slave_16_bit_err_o;
wire slave_16_bit_rty_o;
assign wb_lo_ack_i = slave_08_bit_hit ? slave_08_bit_ack_o : slave_16_bit_ack_o;
assign wb_lo_err_i = slave_08_bit_hit ? slave_08_bit_err_o : slave_16_bit_err_o;
assign wb_lo_rty_i = slave_08_bit_hit ? slave_08_bit_rty_o : slave_16_bit_rty_o;
wire slave_08_bit_cyc_i = wb_lo_cyc_o & slave_08_bit_hit;
wire slave_08_bit_stb_i = wb_lo_stb_o & slave_08_bit_hit;
wire slave_16_bit_cyc_i = wb_lo_cyc_o & ~slave_08_bit_hit;
wire slave_16_bit_stb_i = wb_lo_stb_o & ~slave_08_bit_hit;
assign lo_byte_if_i = slave_08_bit_hit;
wb_slave_model #(.DWIDTH(8), .AWIDTH(5), .ACK_DELAY(2), .SLAVE_RAM_INIT( "wb_slave_08_bit.txt") )
wb_slave_08_bit(
.clk_i(wb_lo_clk_o),
.rst_i(wb_lo_rst_o),
.dat_o(slave_08_bit_dat_o[7:0]),
.dat_i(wb_lo_dat_o[7:0]),
.adr_i(wb_lo_adr_o[4:0]),
.cyc_i(slave_08_bit_cyc_i),
.stb_i(slave_08_bit_stb_i),
.we_i(wb_lo_we_o),
.sel_i(wb_lo_sel_o[0]),
.ack_o(slave_08_bit_ack_o),
.err_o(slave_08_bit_err_o),
.rty_o(slave_08_bit_rty_o)
);
wb_slave_model #(.DWIDTH(16), .AWIDTH(5), .ACK_DELAY(2), .SLAVE_RAM_INIT( "wb_slave_16_bit.txt") )
wb_slave_16_bit(
.clk_i(wb_lo_clk_o),
.rst_i(wb_lo_rst_o),
.dat_o(slave_16_bit_dat_o),
.dat_i(wb_lo_dat_o[15:0]),
.adr_i(wb_lo_adr_o[4:0]),
.cyc_i(slave_16_bit_cyc_i),
.stb_i(slave_16_bit_stb_i),
.we_i(wb_lo_we_o),
.sel_i(wb_lo_sel_o),
.ack_o(slave_16_bit_ack_o),
.err_o(slave_16_bit_err_o),
.rty_o(slave_16_bit_rty_o)
);
 
endmodule
 
 
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
//// ////
//// 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, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
 
`timescale 1ns/10ps
 
 
module tb_dut(
input tb_clk,
input tb_rst
);
 
 
wire wb_hi_clk = tb_clk;
wire wb_hi_rst = tb_rst;
 
wire [31:0] wb_hi_dat_i, wb_hi_dat_o;
wire [31:0] wb_hi_adr_o;
wire wb_hi_cyc_o, wb_hi_stb_o;
wire wb_hi_we_o;
wire [ 3:0] wb_hi_sel_o;
wire wb_hi_ack_i, wb_hi_err_i, wb_hi_rty_i;
 
wire wb_lo_clk_o;
wire wb_lo_rst_o;
 
wire [15:0] wb_lo_dat_i, wb_lo_dat_o;
wire [31:0] wb_lo_adr_o;
wire wb_lo_cyc_o, wb_lo_stb_o;
wire wb_lo_we_o;
wire [1:0] wb_lo_sel_o;
wire wb_lo_ack_i, wb_lo_err_i, wb_lo_rty_i;
wire lo_byte_if_i;
 
 
// --------------------------------------------------------------------
// wb_hi_master_model
wb_master_model wbm(
.clk(wb_hi_clk),
.rst(wb_hi_rst),
.adr(wb_hi_adr_o),
.din(wb_hi_dat_i),
.dout(wb_hi_dat_o),
.cyc(wb_hi_cyc_o),
.stb(wb_hi_stb_o),
.we(wb_hi_we_o),
.sel(wb_hi_sel_o),
.ack(wb_hi_ack_i),
.err(wb_hi_err_i),
.rty(wb_hi_rty_i)
);
 
 
// --------------------------------------------------------------------
// wb_hi_size_bridge
wb_size_bridge i_wb_size_bridge(
.wb_hi_clk_i(wb_hi_clk),
.wb_hi_rst_i(wb_hi_rst),
.wb_hi_dat_o(wb_hi_dat_i),
.wb_hi_dat_i(wb_hi_dat_o),
.wb_hi_adr_i(wb_hi_adr_o),
.wb_hi_cyc_i(wb_hi_cyc_o),
.wb_hi_we_i(wb_hi_we_o),
.wb_hi_stb_i(wb_hi_stb_o),
.wb_hi_sel_i(wb_hi_sel_o),
.wb_hi_ack_o(wb_hi_ack_i),
.wb_hi_err_o(wb_hi_err_i),
.wb_hi_rty_o(wb_hi_rty_i),
.wb_lo_clk_o(wb_lo_clk_o),
.wb_lo_rst_o(wb_lo_rst_o),
.wb_lo_dat_o(wb_lo_dat_o),
.wb_lo_dat_i(wb_lo_dat_i),
.wb_lo_adr_o(wb_lo_adr_o),
.wb_lo_cyc_o(wb_lo_cyc_o),
.wb_lo_we_o(wb_lo_we_o),
.wb_lo_stb_o(wb_lo_stb_o),
.wb_lo_sel_o(wb_lo_sel_o),
.wb_lo_ack_i(wb_lo_ack_i),
.wb_lo_err_i(wb_lo_err_i),
.wb_lo_rty_i(wb_lo_rty_i),
.lo_byte_if_i(lo_byte_if_i)
);
// --------------------------------------------------------------------
// wb_slave_model
wire slave_08_bit_hit = (wb_lo_adr_o[31:24] == 8'h60) & wb_lo_cyc_o;
wire [15:0] slave_08_bit_dat_o;
wire [15:0] slave_16_bit_dat_o;
assign wb_lo_dat_i[15:0] = slave_08_bit_hit ? slave_08_bit_dat_o : slave_16_bit_dat_o;
wire slave_08_bit_ack_o;
wire slave_08_bit_err_o;
wire slave_08_bit_rty_o;
wire slave_16_bit_ack_o;
wire slave_16_bit_err_o;
wire slave_16_bit_rty_o;
assign wb_lo_ack_i = slave_08_bit_hit ? slave_08_bit_ack_o : slave_16_bit_ack_o;
assign wb_lo_err_i = slave_08_bit_hit ? slave_08_bit_err_o : slave_16_bit_err_o;
assign wb_lo_rty_i = slave_08_bit_hit ? slave_08_bit_rty_o : slave_16_bit_rty_o;
wire slave_08_bit_cyc_i = wb_lo_cyc_o & slave_08_bit_hit;
wire slave_08_bit_stb_i = wb_lo_stb_o & slave_08_bit_hit;
wire slave_16_bit_cyc_i = wb_lo_cyc_o & ~slave_08_bit_hit;
wire slave_16_bit_stb_i = wb_lo_stb_o & ~slave_08_bit_hit;
assign lo_byte_if_i = slave_08_bit_hit;
wb_slave_model #(.DWIDTH(8), .AWIDTH(5), .ACK_DELAY(2), .SLAVE_RAM_INIT( "wb_slave_08_bit.txt") )
wb_slave_08_bit(
.clk_i(wb_lo_clk_o),
.rst_i(wb_lo_rst_o),
.dat_o(slave_08_bit_dat_o[7:0]),
.dat_i(wb_lo_dat_o[7:0]),
.adr_i(wb_lo_adr_o[4:0]),
.cyc_i(slave_08_bit_cyc_i),
.stb_i(slave_08_bit_stb_i),
.we_i(wb_lo_we_o),
.sel_i(wb_lo_sel_o[0]),
.ack_o(slave_08_bit_ack_o),
.err_o(slave_08_bit_err_o),
.rty_o(slave_08_bit_rty_o)
);
wb_slave_model #(.DWIDTH(16), .AWIDTH(5), .ACK_DELAY(2), .SLAVE_RAM_INIT( "wb_slave_16_bit.txt") )
wb_slave_16_bit(
.clk_i(wb_lo_clk_o),
.rst_i(wb_lo_rst_o),
.dat_o(slave_16_bit_dat_o),
.dat_i(wb_lo_dat_o[15:0]),
.adr_i(wb_lo_adr_o[4:0]),
.cyc_i(slave_16_bit_cyc_i),
.stb_i(slave_16_bit_stb_i),
.we_i(wb_lo_we_o),
.sel_i(wb_lo_sel_o),
.ack_o(slave_16_bit_ack_o),
.err_o(slave_16_bit_err_o),
.rty_o(slave_16_bit_rty_o)
);
 
endmodule
 
 
/trunk/tb/test/debug/tb_top.v
1,132 → 1,155
// --------------------------------------------------------------------
//
// --------------------------------------------------------------------
 
`timescale 1ns/10ps
 
 
module tb_top();
 
parameter CLK_PERIOD = 10;
 
reg tb_clk, tb_rst;
 
initial
begin
tb_clk <= 1'b1;
tb_rst <= 1'b1;
#(CLK_PERIOD); #(CLK_PERIOD/3);
tb_rst = 1'b0;
end
 
always
#(CLK_PERIOD/2) tb_clk = ~tb_clk;
// --------------------------------------------------------------------
// tb_dut
tb_dut dut( tb_clk, tb_rst );
 
// --------------------------------------------------------------------
// insert test below
 
initial
begin
wait( ~tb_rst );
repeat(2) @(posedge tb_clk);
// 8 bit if
$display("\n^^^- testing 8 bit interface\n");
dut.wbm.wb_cmp(0, 0, 32'h6000_0000, 32'h3322_1100);
dut.wbm.wb_cmp(0, 0, 32'h6000_0004, 32'h7766_5544);
dut.wbm.wb_cmp(0, 0, 32'h6000_0008, 32'hbbaa_9988);
dut.wbm.wb_cmp(0, 0, 32'h6000_000c, 32'hffee_ddcc);
dut.wbm.wb_write(0, 0, 32'h6000_0010, 32'habba_beef);
dut.wbm.wb_write(0, 0, 32'h6000_0014, 32'h1a2b_3c4d);
dut.wbm.wb_write(0, 0, 32'h6000_0018, 32'hcafe_1a7e);
dut.wbm.wb_write(0, 0, 32'h6000_001c, 32'h5a5a_0f0f);
dut.wbm.wb_cmp(0, 0, 32'h6000_0010, 32'habba_beef);
dut.wbm.wb_cmp(0, 0, 32'h6000_0014, 32'h1a2b_3c4d);
dut.wbm.wb_cmp(0, 0, 32'h6000_0018, 32'hcafe_1a7e);
dut.wbm.wb_cmp(0, 0, 32'h6000_001c, 32'h5a5a_0f0f);
dut.wbm.wb_write_sel(0, 0, 4'b0001, 32'h6000_0010, 32'hxxxx_xx00);
dut.wbm.wb_write_sel(0, 0, 4'b0010, 32'h6000_0014, 32'hxxxx_11xx);
dut.wbm.wb_write_sel(0, 0, 4'b0100, 32'h6000_0018, 32'hxx22_xxxx);
dut.wbm.wb_write_sel(0, 0, 4'b1000, 32'h6000_001c, 32'h33xx_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0001, 32'h6000_0010, 32'hxxxx_xx00);
dut.wbm.wb_cmp_sel(0, 0, 4'b0010, 32'h6000_0014, 32'hxxxx_11xx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0100, 32'h6000_0018, 32'hxx22_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b1000, 32'h6000_001c, 32'h33xx_xxxx);
dut.wbm.wb_write_sel(0, 0, 4'b0011, 32'h6000_0000, 32'hxxxx_0ab1);
dut.wbm.wb_write_sel(0, 0, 4'b1100, 32'h6000_0004, 32'h2cd3_xxxx);
dut.wbm.wb_write_sel(0, 0, 4'b0011, 32'h6000_0008, 32'hxxxx_4ef5);
dut.wbm.wb_write_sel(0, 0, 4'b1100, 32'h6000_000c, 32'h0f0f_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0011, 32'h6000_0000, 32'hxxxx_0ab1);
dut.wbm.wb_cmp_sel(0, 0, 4'b1100, 32'h6000_0004, 32'h2cd3_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0011, 32'h6000_0008, 32'hxxxx_4ef5);
dut.wbm.wb_cmp_sel(0, 0, 4'b1100, 32'h6000_000c, 32'h0f0f_xxxx);
// 16 bit if
$display("\n^^^- testing 16 bit interface\n");
dut.wbm.wb_cmp(0, 0, 32'ha000_0000, 32'h3322_1100);
dut.wbm.wb_cmp(0, 0, 32'ha000_0004, 32'h7766_5544);
dut.wbm.wb_cmp(0, 0, 32'ha000_0008, 32'hbbaa_9988);
dut.wbm.wb_cmp(0, 0, 32'ha000_000c, 32'hffee_ddcc);
dut.wbm.wb_write(0, 0, 32'ha000_0010, 32'habba_beef);
dut.wbm.wb_write(0, 0, 32'ha000_0014, 32'h1a2b_3c4d);
dut.wbm.wb_write(0, 0, 32'ha000_0018, 32'hcafe_1a7e);
dut.wbm.wb_write(0, 0, 32'ha000_001c, 32'h5a5a_0f0f);
dut.wbm.wb_cmp(0, 0, 32'ha000_0010, 32'habba_beef);
dut.wbm.wb_cmp(0, 0, 32'ha000_0014, 32'h1a2b_3c4d);
dut.wbm.wb_cmp(0, 0, 32'ha000_0018, 32'hcafe_1a7e);
dut.wbm.wb_cmp(0, 0, 32'ha000_001c, 32'h5a5a_0f0f);
dut.wbm.wb_write_sel(0, 0, 4'b0011, 32'ha000_0000, 32'hxxxx_0ab1);
dut.wbm.wb_write_sel(0, 0, 4'b1100, 32'ha000_0004, 32'h2cd3_xxxx);
dut.wbm.wb_write_sel(0, 0, 4'b0011, 32'ha000_0008, 32'hxxxx_4ef5);
dut.wbm.wb_write_sel(0, 0, 4'b1100, 32'ha000_000c, 32'h0f0f_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0011, 32'ha000_0000, 32'hxxxx_0ab1);
dut.wbm.wb_cmp_sel(0, 0, 4'b1100, 32'ha000_0004, 32'h2cd3_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0011, 32'ha000_0008, 32'hxxxx_4ef5);
dut.wbm.wb_cmp_sel(0, 0, 4'b1100, 32'ha000_000c, 32'h0f0f_xxxx);
dut.wbm.wb_write_sel(0, 0, 4'b0001, 32'h0000_0010, 32'hxxxx_xx00);
dut.wbm.wb_write_sel(0, 0, 4'b0010, 32'h0000_0014, 32'hxxxx_11xx);
dut.wbm.wb_write_sel(0, 0, 4'b0100, 32'h0000_0018, 32'hxx22_xxxx);
dut.wbm.wb_write_sel(0, 0, 4'b1000, 32'h0000_001c, 32'h33xx_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0001, 32'h0000_0010, 32'hxxxx_xx00);
dut.wbm.wb_cmp_sel(0, 0, 4'b0010, 32'h0000_0014, 32'hxxxx_11xx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0100, 32'h0000_0018, 32'hxx22_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b1000, 32'h0000_001c, 32'h33xx_xxxx);
// do illegal byte boundary access
$display("\n^^^- testing illegal byte boundary access\n");
dut.wbm.wb_write_sel(0, 0, 4'b0110, 32'ha000_0020, 32'hxxba_adxx);
repeat(2) @(posedge tb_clk);
$display("\n^^^---------------------------------\n");
$display("^^^- Testbench done. %t.\n", $time);
$stop();
end
endmodule
 
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
//// ////
//// 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, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
 
`timescale 1ns/10ps
 
 
module tb_top();
 
parameter CLK_PERIOD = 10;
 
reg tb_clk, tb_rst;
 
initial
begin
tb_clk <= 1'b1;
tb_rst <= 1'b1;
#(CLK_PERIOD); #(CLK_PERIOD/3);
tb_rst = 1'b0;
end
 
always
#(CLK_PERIOD/2) tb_clk = ~tb_clk;
// --------------------------------------------------------------------
// tb_dut
tb_dut dut( tb_clk, tb_rst );
 
// --------------------------------------------------------------------
// insert test below
 
initial
begin
wait( ~tb_rst );
repeat(2) @(posedge tb_clk);
// 8 bit if
$display("\n^^^- testing 8 bit interface\n");
dut.wbm.wb_cmp(0, 0, 32'h6000_0000, 32'h3322_1100);
dut.wbm.wb_cmp(0, 0, 32'h6000_0004, 32'h7766_5544);
dut.wbm.wb_cmp(0, 0, 32'h6000_0008, 32'hbbaa_9988);
dut.wbm.wb_cmp(0, 0, 32'h6000_000c, 32'hffee_ddcc);
dut.wbm.wb_write(0, 0, 32'h6000_0010, 32'habba_beef);
dut.wbm.wb_write(0, 0, 32'h6000_0014, 32'h1a2b_3c4d);
dut.wbm.wb_write(0, 0, 32'h6000_0018, 32'hcafe_1a7e);
dut.wbm.wb_write(0, 0, 32'h6000_001c, 32'h5a5a_0f0f);
dut.wbm.wb_cmp(0, 0, 32'h6000_0010, 32'habba_beef);
dut.wbm.wb_cmp(0, 0, 32'h6000_0014, 32'h1a2b_3c4d);
dut.wbm.wb_cmp(0, 0, 32'h6000_0018, 32'hcafe_1a7e);
dut.wbm.wb_cmp(0, 0, 32'h6000_001c, 32'h5a5a_0f0f);
dut.wbm.wb_write_sel(0, 0, 4'b0001, 32'h6000_0010, 32'hxxxx_xx00);
dut.wbm.wb_write_sel(0, 0, 4'b0010, 32'h6000_0014, 32'hxxxx_11xx);
dut.wbm.wb_write_sel(0, 0, 4'b0100, 32'h6000_0018, 32'hxx22_xxxx);
dut.wbm.wb_write_sel(0, 0, 4'b1000, 32'h6000_001c, 32'h33xx_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0001, 32'h6000_0010, 32'hxxxx_xx00);
dut.wbm.wb_cmp_sel(0, 0, 4'b0010, 32'h6000_0014, 32'hxxxx_11xx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0100, 32'h6000_0018, 32'hxx22_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b1000, 32'h6000_001c, 32'h33xx_xxxx);
dut.wbm.wb_write_sel(0, 0, 4'b0011, 32'h6000_0000, 32'hxxxx_0ab1);
dut.wbm.wb_write_sel(0, 0, 4'b1100, 32'h6000_0004, 32'h2cd3_xxxx);
dut.wbm.wb_write_sel(0, 0, 4'b0011, 32'h6000_0008, 32'hxxxx_4ef5);
dut.wbm.wb_write_sel(0, 0, 4'b1100, 32'h6000_000c, 32'h0f0f_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0011, 32'h6000_0000, 32'hxxxx_0ab1);
dut.wbm.wb_cmp_sel(0, 0, 4'b1100, 32'h6000_0004, 32'h2cd3_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0011, 32'h6000_0008, 32'hxxxx_4ef5);
dut.wbm.wb_cmp_sel(0, 0, 4'b1100, 32'h6000_000c, 32'h0f0f_xxxx);
// 16 bit if
$display("\n^^^- testing 16 bit interface\n");
dut.wbm.wb_cmp(0, 0, 32'ha000_0000, 32'h3322_1100);
dut.wbm.wb_cmp(0, 0, 32'ha000_0004, 32'h7766_5544);
dut.wbm.wb_cmp(0, 0, 32'ha000_0008, 32'hbbaa_9988);
dut.wbm.wb_cmp(0, 0, 32'ha000_000c, 32'hffee_ddcc);
dut.wbm.wb_write(0, 0, 32'ha000_0010, 32'habba_beef);
dut.wbm.wb_write(0, 0, 32'ha000_0014, 32'h1a2b_3c4d);
dut.wbm.wb_write(0, 0, 32'ha000_0018, 32'hcafe_1a7e);
dut.wbm.wb_write(0, 0, 32'ha000_001c, 32'h5a5a_0f0f);
dut.wbm.wb_cmp(0, 0, 32'ha000_0010, 32'habba_beef);
dut.wbm.wb_cmp(0, 0, 32'ha000_0014, 32'h1a2b_3c4d);
dut.wbm.wb_cmp(0, 0, 32'ha000_0018, 32'hcafe_1a7e);
dut.wbm.wb_cmp(0, 0, 32'ha000_001c, 32'h5a5a_0f0f);
dut.wbm.wb_write_sel(0, 0, 4'b0011, 32'ha000_0000, 32'hxxxx_0ab1);
dut.wbm.wb_write_sel(0, 0, 4'b1100, 32'ha000_0004, 32'h2cd3_xxxx);
dut.wbm.wb_write_sel(0, 0, 4'b0011, 32'ha000_0008, 32'hxxxx_4ef5);
dut.wbm.wb_write_sel(0, 0, 4'b1100, 32'ha000_000c, 32'h0f0f_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0011, 32'ha000_0000, 32'hxxxx_0ab1);
dut.wbm.wb_cmp_sel(0, 0, 4'b1100, 32'ha000_0004, 32'h2cd3_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0011, 32'ha000_0008, 32'hxxxx_4ef5);
dut.wbm.wb_cmp_sel(0, 0, 4'b1100, 32'ha000_000c, 32'h0f0f_xxxx);
dut.wbm.wb_write_sel(0, 0, 4'b0001, 32'h0000_0010, 32'hxxxx_xx00);
dut.wbm.wb_write_sel(0, 0, 4'b0010, 32'h0000_0014, 32'hxxxx_11xx);
dut.wbm.wb_write_sel(0, 0, 4'b0100, 32'h0000_0018, 32'hxx22_xxxx);
dut.wbm.wb_write_sel(0, 0, 4'b1000, 32'h0000_001c, 32'h33xx_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0001, 32'h0000_0010, 32'hxxxx_xx00);
dut.wbm.wb_cmp_sel(0, 0, 4'b0010, 32'h0000_0014, 32'hxxxx_11xx);
dut.wbm.wb_cmp_sel(0, 0, 4'b0100, 32'h0000_0018, 32'hxx22_xxxx);
dut.wbm.wb_cmp_sel(0, 0, 4'b1000, 32'h0000_001c, 32'h33xx_xxxx);
// do illegal byte boundary access
$display("\n^^^- testing illegal byte boundary access\n");
dut.wbm.wb_write_sel(0, 0, 4'b0110, 32'ha000_0020, 32'hxxba_adxx);
repeat(2) @(posedge tb_clk);
$display("\n^^^---------------------------------\n");
$display("^^^- Testbench done. %t.\n", $time);
$stop();
end
endmodule
 
/trunk/tb/models/wb_slave_model.v
1,123 → 1,146
// --------------------------------------------------------------------
//
// --------------------------------------------------------------------
 
`timescale 1ns/10ps
 
 
module wb_slave_model( clk_i, rst_i, dat_o, dat_i, adr_i,
cyc_i, stb_i, we_i, sel_i,
ack_o, err_o, rty_o );
 
parameter DWIDTH = 8;
parameter AWIDTH = 8;
parameter ACK_DELAY = 2;
parameter SLAVE_RAM_INIT = "wb_slave_model.txt";
input clk_i;
input rst_i;
output [DWIDTH-1:0] dat_o;
input [DWIDTH-1:0] dat_i;
input [AWIDTH-1:0] adr_i;
input cyc_i;
input stb_i;
input we_i;
input [( (DWIDTH/8) - 1 ):0] sel_i;
output ack_o;
output err_o;
output rty_o;
// --------------------------------------------------------------------
// slave ram
reg [7:0] ram[2**AWIDTH-1:0];
initial
$readmemh( SLAVE_RAM_INIT, ram );
 
// --------------------------------------------------------------------
//
generate
case( DWIDTH )
8: begin
initial
$display( "###- wb_slave_model(): WISHBONE 8 BIT SLAVE MODEL INSTANTIATED " );
always @ (posedge clk_i)
if (we_i & cyc_i & stb_i & sel_i[0])
ram[adr_i] <= dat_i[7:0];
assign dat_o = ram[adr_i];
end
16: begin
initial
$display( "###- wb_slave_model(): WISHBONE 16 BIT SLAVE MODEL INSTANTIATED " );
always @ (posedge clk_i)
if (we_i & cyc_i & stb_i & sel_i[0])
ram[{adr_i[AWIDTH-1:1], 1'b0}] <= dat_i[7:0];
always @ (posedge clk_i)
if (we_i & cyc_i & stb_i & sel_i[1])
ram[{adr_i[AWIDTH-1:1], 1'b1}] <= dat_i[15:8];
assign dat_o = { ram[{adr_i[AWIDTH-1:1], 1'b1}], ram[{adr_i[AWIDTH-1:1], 1'b0}] };
end
32: begin
initial
begin
$display( "###- wb_slave_model(): WISHBONE 32 BIT SLAVE MODEL INSTANTIATED " );
$display( "###- wb_slave_model(): Not yet supported " );
$stop();
end
end
default: begin
localparam SLAVE_SIZE = -1;
initial
begin
$display( "!!!- wb_slave_model(): invalad DWIDTH parameter" );
$stop();
end
end
endcase
endgenerate
 
// --------------------------------------------------------------------
// ack delay
reg ack_delayed;
initial
ack_delayed = 1'b0;
always @(posedge clk_i or cyc_i or stb_i)
begin
if(cyc_i & stb_i)
begin
ack_delayed = 1'b0;
repeat(ACK_DELAY) @(posedge clk_i);
if(cyc_i & stb_i)
ack_delayed = 1'b1;
else
ack_delayed = 1'b0;
end
else
ack_delayed = 1'b0;
end
// --------------------------------------------------------------------
// assign outputs
assign ack_o = ack_delayed;
assign err_o = 1'b0;
assign rty_o = 1'b0;
 
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
//// ////
//// 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, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
 
`timescale 1ns/10ps
 
 
module wb_slave_model( clk_i, rst_i, dat_o, dat_i, adr_i,
cyc_i, stb_i, we_i, sel_i,
ack_o, err_o, rty_o );
 
parameter DWIDTH = 8;
parameter AWIDTH = 8;
parameter ACK_DELAY = 2;
parameter SLAVE_RAM_INIT = "wb_slave_model.txt";
input clk_i;
input rst_i;
output [DWIDTH-1:0] dat_o;
input [DWIDTH-1:0] dat_i;
input [AWIDTH-1:0] adr_i;
input cyc_i;
input stb_i;
input we_i;
input [( (DWIDTH/8) - 1 ):0] sel_i;
output ack_o;
output err_o;
output rty_o;
// --------------------------------------------------------------------
// slave ram
reg [7:0] ram[2**AWIDTH-1:0];
initial
$readmemh( SLAVE_RAM_INIT, ram );
 
// --------------------------------------------------------------------
//
generate
case( DWIDTH )
8: begin
initial
$display( "###- wb_slave_model(): WISHBONE 8 BIT SLAVE MODEL INSTANTIATED " );
always @ (posedge clk_i)
if (we_i & cyc_i & stb_i & sel_i[0])
ram[adr_i] <= dat_i[7:0];
assign dat_o = ram[adr_i];
end
16: begin
initial
$display( "###- wb_slave_model(): WISHBONE 16 BIT SLAVE MODEL INSTANTIATED " );
always @ (posedge clk_i)
if (we_i & cyc_i & stb_i & sel_i[0])
ram[{adr_i[AWIDTH-1:1], 1'b0}] <= dat_i[7:0];
always @ (posedge clk_i)
if (we_i & cyc_i & stb_i & sel_i[1])
ram[{adr_i[AWIDTH-1:1], 1'b1}] <= dat_i[15:8];
assign dat_o = { ram[{adr_i[AWIDTH-1:1], 1'b1}], ram[{adr_i[AWIDTH-1:1], 1'b0}] };
end
32: begin
initial
begin
$display( "###- wb_slave_model(): WISHBONE 32 BIT SLAVE MODEL INSTANTIATED " );
$display( "###- wb_slave_model(): Not yet supported " );
$stop();
end
end
default: begin
localparam SLAVE_SIZE = -1;
initial
begin
$display( "!!!- wb_slave_model(): invalad DWIDTH parameter" );
$stop();
end
end
endcase
endgenerate
 
// --------------------------------------------------------------------
// ack delay
reg ack_delayed;
initial
ack_delayed = 1'b0;
always @(posedge clk_i or cyc_i or stb_i)
begin
if(cyc_i & stb_i)
begin
ack_delayed = 1'b0;
repeat(ACK_DELAY) @(posedge clk_i);
if(cyc_i & stb_i)
ack_delayed = 1'b1;
else
ack_delayed = 1'b0;
end
else
ack_delayed = 1'b0;
end
// --------------------------------------------------------------------
// assign outputs
assign ack_o = ack_delayed;
assign err_o = 1'b0;
assign rty_o = 1'b0;
 
endmodule
/trunk/src/wb_size_bridge.v
1,310 → 1,333
// --------------------------------------------------------------------
//
// --------------------------------------------------------------------
 
`timescale 1ns/10ps
 
 
module wb_size_bridge(
input wb_hi_clk_i,
input wb_hi_rst_i,
output [31:0] wb_hi_dat_o,
input [31:0] wb_hi_dat_i,
input [31:0] wb_hi_adr_i,
input wb_hi_cyc_i,
input wb_hi_stb_i,
input wb_hi_we_i,
input [3:0] wb_hi_sel_i,
output wb_hi_ack_o,
output wb_hi_err_o,
output wb_hi_rty_o,
 
output wb_lo_clk_o,
output wb_lo_rst_o,
input [15:0] wb_lo_dat_i,
output [15:0] wb_lo_dat_o,
output [31:0] wb_lo_adr_o,
output wb_lo_cyc_o,
output wb_lo_stb_o,
output wb_lo_we_o,
output [1:0] wb_lo_sel_o,
input wb_lo_ack_i,
input wb_lo_err_i,
input wb_lo_rty_i,
input lo_byte_if_i
);
 
// --------------------------------------------------------------------
// state machine encoder
reg [2:0] state_enc;
wire state_enc_3_more_chunks = state_enc[2];
wire state_enc_1_more_chunks = state_enc[1];
wire state_enc_error = state_enc[0];
always @(*)
case( { lo_byte_if_i, wb_hi_sel_i } )
5'b1_0001: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b1_0010: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b1_0100: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b1_1000: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b1_0011: state_enc = { 1'b0, 1'b1, 1'b0 };
5'b1_1100: state_enc = { 1'b0, 1'b1, 1'b0 };
5'b1_1111: state_enc = { 1'b1, 1'b0, 1'b0 };
5'b0_0001: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b0_0010: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b0_0100: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b0_1000: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b0_0011: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b0_1100: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b0_1111: state_enc = { 1'b0, 1'b1, 1'b0 };
default: state_enc = { 1'b0, 1'b0, 1'b1 };
endcase
// --------------------------------------------------------------------
// state machine
 
localparam STATE_DONT_CARE = 4'b????;
localparam STATE_PASS_THROUGH = 4'b0001;
localparam STATE_1_MORE_CHUNK = 4'b0010;
localparam STATE_2_MORE_CHUNK = 4'b0100;
localparam STATE_3_MORE_CHUNK = 4'b1000;
 
reg [3:0] state;
reg [3:0] next_state;
 
always @(posedge wb_hi_clk_i or posedge wb_hi_rst_i)
if(wb_hi_rst_i)
state <= STATE_PASS_THROUGH;
else
state <= next_state;
 
always @(*)
case( state )
STATE_PASS_THROUGH: if( state_enc_1_more_chunks & wb_lo_ack_i & wb_hi_stb_i & wb_hi_cyc_i )
next_state = STATE_1_MORE_CHUNK;
else if( state_enc_3_more_chunks & wb_lo_ack_i & wb_hi_stb_i & wb_hi_cyc_i )
next_state = STATE_3_MORE_CHUNK;
else
next_state = STATE_PASS_THROUGH;
 
STATE_3_MORE_CHUNK: if( wb_lo_ack_i )
next_state = STATE_2_MORE_CHUNK;
else
next_state = STATE_3_MORE_CHUNK;
STATE_2_MORE_CHUNK: if( wb_lo_ack_i )
next_state = STATE_1_MORE_CHUNK;
else
next_state = STATE_2_MORE_CHUNK;
 
STATE_1_MORE_CHUNK: if( wb_lo_ack_i )
next_state = STATE_PASS_THROUGH;
else
next_state = STATE_1_MORE_CHUNK;
default: next_state = STATE_PASS_THROUGH;
endcase
 
// --------------------------------------------------------------------
// byte enable & select
reg [3:0] byte_enable;
localparam BYTE_N_ENABLED = 4'b0000;
localparam BYTE_0_ENABLED = 4'b0001;
localparam BYTE_1_ENABLED = 4'b0010;
localparam BYTE_2_ENABLED = 4'b0100;
localparam BYTE_3_ENABLED = 4'b1000;
reg [1:0] byte_select;
localparam BYTE_0_SELECTED = 2'b00;
localparam BYTE_1_SELECTED = 2'b01;
localparam BYTE_2_SELECTED = 2'b10;
localparam BYTE_3_SELECTED = 2'b11;
localparam BYTE_X_SELECTED = 2'b??;
 
always @(*)
casez( { lo_byte_if_i, wb_hi_sel_i, state } )
{ 1'b1, 4'b0001, STATE_PASS_THROUGH }: byte_enable = BYTE_0_ENABLED;
{ 1'b1, 4'b0010, STATE_PASS_THROUGH }: byte_enable = BYTE_1_ENABLED;
{ 1'b1, 4'b0100, STATE_PASS_THROUGH }: byte_enable = BYTE_2_ENABLED;
{ 1'b1, 4'b1000, STATE_PASS_THROUGH }: byte_enable = BYTE_3_ENABLED;
{ 1'b1, 4'b0011, STATE_PASS_THROUGH }: byte_enable = BYTE_0_ENABLED;
{ 1'b1, 4'b0011, STATE_1_MORE_CHUNK }: byte_enable = BYTE_1_ENABLED;
{ 1'b1, 4'b1100, STATE_PASS_THROUGH }: byte_enable = BYTE_2_ENABLED;
{ 1'b1, 4'b1100, STATE_1_MORE_CHUNK }: byte_enable = BYTE_3_ENABLED;
{ 1'b1, 4'b1111, STATE_PASS_THROUGH }: byte_enable = BYTE_0_ENABLED;
{ 1'b1, 4'b1111, STATE_3_MORE_CHUNK }: byte_enable = BYTE_1_ENABLED;
{ 1'b1, 4'b1111, STATE_2_MORE_CHUNK }: byte_enable = BYTE_2_ENABLED;
{ 1'b1, 4'b1111, STATE_1_MORE_CHUNK }: byte_enable = BYTE_3_ENABLED;
{ 1'b0, 4'b????, STATE_DONT_CARE }: byte_enable = BYTE_N_ENABLED;
default: byte_enable = BYTE_N_ENABLED;
endcase
 
always @(*)
case( byte_enable )
BYTE_0_ENABLED: byte_select = BYTE_0_SELECTED;
BYTE_1_ENABLED: byte_select = BYTE_1_SELECTED;
BYTE_2_ENABLED: byte_select = BYTE_2_SELECTED;
BYTE_3_ENABLED: byte_select = BYTE_3_SELECTED;
default: byte_select = 2'bxx;
endcase
 
// --------------------------------------------------------------------
// word enable & select
reg [1:0] word_enable;
localparam WORD_N_ENABLED = 2'b00;
localparam WORD_0_ENABLED = 2'b01;
localparam WORD_1_ENABLED = 2'b10;
reg word_select;
localparam WORD_0_SELECTED = 1'b0;
localparam WORD_1_SELECTED = 1'b1;
localparam WORD_X_SELECTED = 1'b?;
 
always @(*)
casez( { lo_byte_if_i, wb_hi_sel_i, state } )
{ 1'b0, 4'b0011, STATE_PASS_THROUGH }: word_enable = WORD_0_ENABLED;
{ 1'b0, 4'b1100, STATE_PASS_THROUGH }: word_enable = WORD_1_ENABLED;
{ 1'b0, 4'b0001, STATE_PASS_THROUGH }: word_enable = WORD_0_ENABLED;
{ 1'b0, 4'b0010, STATE_PASS_THROUGH }: word_enable = WORD_0_ENABLED;
{ 1'b0, 4'b0100, STATE_PASS_THROUGH }: word_enable = WORD_1_ENABLED;
{ 1'b0, 4'b1000, STATE_PASS_THROUGH }: word_enable = WORD_1_ENABLED;
{ 1'b0, 4'b1111, STATE_PASS_THROUGH }: word_enable = WORD_0_ENABLED;
{ 1'b0, 4'b1111, STATE_1_MORE_CHUNK }: word_enable = WORD_1_ENABLED;
{ 1'b1, 4'b????, STATE_DONT_CARE }: word_enable = WORD_N_ENABLED;
default: word_enable = WORD_N_ENABLED;
endcase
 
always @(*)
case( word_enable )
WORD_0_ENABLED: word_select = WORD_0_SELECTED;
WORD_1_ENABLED: word_select = WORD_1_SELECTED;
default: word_select = 1'bx;
endcase
 
// --------------------------------------------------------------------
// write mux
reg [1:0] byte_write_mux_enc;
always @(*)
casez( {lo_byte_if_i, byte_select, word_select} )
{ 1'b1, BYTE_0_SELECTED, WORD_X_SELECTED }: byte_write_mux_enc = 2'b00;
{ 1'b1, BYTE_1_SELECTED, WORD_X_SELECTED }: byte_write_mux_enc = 2'b01;
{ 1'b1, BYTE_2_SELECTED, WORD_X_SELECTED }: byte_write_mux_enc = 2'b10;
{ 1'b1, BYTE_3_SELECTED, WORD_X_SELECTED }: byte_write_mux_enc = 2'b11;
{ 1'b0, BYTE_X_SELECTED, WORD_0_SELECTED }: byte_write_mux_enc = 2'b00;
{ 1'b0, BYTE_X_SELECTED, WORD_1_SELECTED }: byte_write_mux_enc = 2'b10;
default: byte_write_mux_enc = 2'b00;
endcase
reg [7:0] byte_write_mux;
 
always @(*)
case( byte_write_mux_enc )
2'b00: byte_write_mux = wb_hi_dat_i[7:0];
2'b01: byte_write_mux = wb_hi_dat_i[15:8];
2'b10: byte_write_mux = wb_hi_dat_i[23:16];
2'b11: byte_write_mux = wb_hi_dat_i[31:24];
default: byte_write_mux = wb_hi_dat_i[7:0];
endcase
reg [7:0] word_write_mux;
 
always @(*)
case( word_select )
WORD_0_SELECTED: word_write_mux = wb_hi_dat_i[15:8];
WORD_1_SELECTED: word_write_mux = wb_hi_dat_i[31:24];
default: word_write_mux = wb_hi_dat_i[15:8];
endcase
// --------------------------------------------------------------------
// read buffer & bypass mux
// low side input mux
wire [7:0] read_word_lo_mux = wb_lo_dat_i[7:0];
wire [7:0] read_word_hi_mux = ( word_enable[0] | word_enable[1] )? wb_lo_dat_i[15:8] : wb_lo_dat_i[7:0];
reg [31:0] read_buffer;
wire read_buffer_0_enable = (byte_enable[0] | word_enable[0]) & ~wb_hi_we_i;
wire read_buffer_1_enable = (byte_enable[1] | word_enable[0]) & ~wb_hi_we_i;
wire read_buffer_2_enable = (byte_enable[2] | word_enable[1]) & ~wb_hi_we_i;
wire read_buffer_3_enable = (byte_enable[3] | word_enable[1]) & ~wb_hi_we_i;
always @(posedge wb_hi_clk_i)
if( read_buffer_0_enable )
read_buffer[7:0] <= read_word_lo_mux;
always @(posedge wb_hi_clk_i)
if( read_buffer_1_enable )
read_buffer[15:8] <= read_word_hi_mux;
always @(posedge wb_hi_clk_i)
if( read_buffer_2_enable )
read_buffer[23:16] <= read_word_lo_mux;
always @(posedge wb_hi_clk_i)
if( read_buffer_3_enable )
read_buffer[31:24] <= read_word_hi_mux;
wire [31:0] read_buffer_mux;
// bypass read mux
assign read_buffer_mux[7:0] = read_buffer_0_enable ? read_word_lo_mux : read_buffer[7:0];
assign read_buffer_mux[15:8] = read_buffer_1_enable ? read_word_hi_mux : read_buffer[15:8];
assign read_buffer_mux[23:16] = read_buffer_2_enable ? read_word_lo_mux : read_buffer[23:16];
assign read_buffer_mux[31:24] = read_buffer_3_enable ? read_word_hi_mux : read_buffer[31:24];
// --------------------------------------------------------------------
// misc logic
wire [1:0] lo_addr_bits;
assign lo_addr_bits = ( |byte_enable ) ? byte_select : { word_select, 1'b0 };
wire all_done = ( ~(|state_enc) & (state == STATE_PASS_THROUGH) ) |
( |state_enc & (state == STATE_1_MORE_CHUNK) );
reg [1:0] wb_lo_sel_r;
always @(*)
casez( { lo_byte_if_i, wb_hi_sel_i, state } )
{ 1'b0, 4'b0001, STATE_PASS_THROUGH }: wb_lo_sel_r = 2'b01;
{ 1'b0, 4'b0010, STATE_PASS_THROUGH }: wb_lo_sel_r = 2'b10;
{ 1'b0, 4'b0100, STATE_PASS_THROUGH }: wb_lo_sel_r = 2'b01;
{ 1'b0, 4'b1000, STATE_PASS_THROUGH }: wb_lo_sel_r = 2'b10;
default: wb_lo_sel_r = 2'b11;
endcase
 
// --------------------------------------------------------------------
// output port assignments
assign wb_hi_dat_o = read_buffer_mux;
assign wb_hi_err_o = (wb_lo_err_i | state_enc_error) & wb_hi_stb_i & wb_hi_cyc_i;
assign wb_hi_rty_o = wb_lo_rty_i;
assign wb_hi_ack_o = all_done & wb_hi_stb_i & wb_hi_cyc_i & wb_lo_ack_i;
assign wb_lo_adr_o = { wb_hi_adr_i[31:2], lo_addr_bits };
assign wb_lo_clk_o = wb_hi_clk_i;
assign wb_lo_rst_o = wb_hi_rst_i;
assign wb_lo_cyc_o = wb_hi_cyc_i;
assign wb_lo_stb_o = wb_hi_stb_i;
assign wb_lo_we_o = wb_hi_we_i & wb_hi_stb_i & wb_hi_cyc_i;
assign wb_lo_dat_o = {word_write_mux, byte_write_mux};
assign wb_lo_sel_o = wb_lo_sel_r;
 
endmodule
 
 
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
//// ////
//// 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, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
 
`timescale 1ns/10ps
 
 
module wb_size_bridge(
input wb_hi_clk_i,
input wb_hi_rst_i,
output [31:0] wb_hi_dat_o,
input [31:0] wb_hi_dat_i,
input [31:0] wb_hi_adr_i,
input wb_hi_cyc_i,
input wb_hi_stb_i,
input wb_hi_we_i,
input [3:0] wb_hi_sel_i,
output wb_hi_ack_o,
output wb_hi_err_o,
output wb_hi_rty_o,
 
output wb_lo_clk_o,
output wb_lo_rst_o,
input [15:0] wb_lo_dat_i,
output [15:0] wb_lo_dat_o,
output [31:0] wb_lo_adr_o,
output wb_lo_cyc_o,
output wb_lo_stb_o,
output wb_lo_we_o,
output [1:0] wb_lo_sel_o,
input wb_lo_ack_i,
input wb_lo_err_i,
input wb_lo_rty_i,
input lo_byte_if_i
);
 
// --------------------------------------------------------------------
// state machine encoder
reg [2:0] state_enc;
wire state_enc_3_more_chunks = state_enc[2];
wire state_enc_1_more_chunks = state_enc[1];
wire state_enc_error = state_enc[0];
always @(*)
case( { lo_byte_if_i, wb_hi_sel_i } )
5'b1_0001: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b1_0010: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b1_0100: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b1_1000: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b1_0011: state_enc = { 1'b0, 1'b1, 1'b0 };
5'b1_1100: state_enc = { 1'b0, 1'b1, 1'b0 };
5'b1_1111: state_enc = { 1'b1, 1'b0, 1'b0 };
5'b0_0001: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b0_0010: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b0_0100: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b0_1000: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b0_0011: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b0_1100: state_enc = { 1'b0, 1'b0, 1'b0 };
5'b0_1111: state_enc = { 1'b0, 1'b1, 1'b0 };
default: state_enc = { 1'b0, 1'b0, 1'b1 };
endcase
// --------------------------------------------------------------------
// state machine
 
localparam STATE_DONT_CARE = 4'b????;
localparam STATE_PASS_THROUGH = 4'b0001;
localparam STATE_1_MORE_CHUNK = 4'b0010;
localparam STATE_2_MORE_CHUNK = 4'b0100;
localparam STATE_3_MORE_CHUNK = 4'b1000;
 
reg [3:0] state;
reg [3:0] next_state;
 
always @(posedge wb_hi_clk_i or posedge wb_hi_rst_i)
if(wb_hi_rst_i)
state <= STATE_PASS_THROUGH;
else
state <= next_state;
 
always @(*)
case( state )
STATE_PASS_THROUGH: if( state_enc_1_more_chunks & wb_lo_ack_i & wb_hi_stb_i & wb_hi_cyc_i )
next_state = STATE_1_MORE_CHUNK;
else if( state_enc_3_more_chunks & wb_lo_ack_i & wb_hi_stb_i & wb_hi_cyc_i )
next_state = STATE_3_MORE_CHUNK;
else
next_state = STATE_PASS_THROUGH;
 
STATE_3_MORE_CHUNK: if( wb_lo_ack_i )
next_state = STATE_2_MORE_CHUNK;
else
next_state = STATE_3_MORE_CHUNK;
STATE_2_MORE_CHUNK: if( wb_lo_ack_i )
next_state = STATE_1_MORE_CHUNK;
else
next_state = STATE_2_MORE_CHUNK;
 
STATE_1_MORE_CHUNK: if( wb_lo_ack_i )
next_state = STATE_PASS_THROUGH;
else
next_state = STATE_1_MORE_CHUNK;
default: next_state = STATE_PASS_THROUGH;
endcase
 
// --------------------------------------------------------------------
// byte enable & select
reg [3:0] byte_enable;
localparam BYTE_N_ENABLED = 4'b0000;
localparam BYTE_0_ENABLED = 4'b0001;
localparam BYTE_1_ENABLED = 4'b0010;
localparam BYTE_2_ENABLED = 4'b0100;
localparam BYTE_3_ENABLED = 4'b1000;
reg [1:0] byte_select;
localparam BYTE_0_SELECTED = 2'b00;
localparam BYTE_1_SELECTED = 2'b01;
localparam BYTE_2_SELECTED = 2'b10;
localparam BYTE_3_SELECTED = 2'b11;
localparam BYTE_X_SELECTED = 2'b??;
 
always @(*)
casez( { lo_byte_if_i, wb_hi_sel_i, state } )
{ 1'b1, 4'b0001, STATE_PASS_THROUGH }: byte_enable = BYTE_0_ENABLED;
{ 1'b1, 4'b0010, STATE_PASS_THROUGH }: byte_enable = BYTE_1_ENABLED;
{ 1'b1, 4'b0100, STATE_PASS_THROUGH }: byte_enable = BYTE_2_ENABLED;
{ 1'b1, 4'b1000, STATE_PASS_THROUGH }: byte_enable = BYTE_3_ENABLED;
{ 1'b1, 4'b0011, STATE_PASS_THROUGH }: byte_enable = BYTE_0_ENABLED;
{ 1'b1, 4'b0011, STATE_1_MORE_CHUNK }: byte_enable = BYTE_1_ENABLED;
{ 1'b1, 4'b1100, STATE_PASS_THROUGH }: byte_enable = BYTE_2_ENABLED;
{ 1'b1, 4'b1100, STATE_1_MORE_CHUNK }: byte_enable = BYTE_3_ENABLED;
{ 1'b1, 4'b1111, STATE_PASS_THROUGH }: byte_enable = BYTE_0_ENABLED;
{ 1'b1, 4'b1111, STATE_3_MORE_CHUNK }: byte_enable = BYTE_1_ENABLED;
{ 1'b1, 4'b1111, STATE_2_MORE_CHUNK }: byte_enable = BYTE_2_ENABLED;
{ 1'b1, 4'b1111, STATE_1_MORE_CHUNK }: byte_enable = BYTE_3_ENABLED;
{ 1'b0, 4'b????, STATE_DONT_CARE }: byte_enable = BYTE_N_ENABLED;
default: byte_enable = BYTE_N_ENABLED;
endcase
 
always @(*)
case( byte_enable )
BYTE_0_ENABLED: byte_select = BYTE_0_SELECTED;
BYTE_1_ENABLED: byte_select = BYTE_1_SELECTED;
BYTE_2_ENABLED: byte_select = BYTE_2_SELECTED;
BYTE_3_ENABLED: byte_select = BYTE_3_SELECTED;
default: byte_select = 2'bxx;
endcase
 
// --------------------------------------------------------------------
// word enable & select
reg [1:0] word_enable;
localparam WORD_N_ENABLED = 2'b00;
localparam WORD_0_ENABLED = 2'b01;
localparam WORD_1_ENABLED = 2'b10;
reg word_select;
localparam WORD_0_SELECTED = 1'b0;
localparam WORD_1_SELECTED = 1'b1;
localparam WORD_X_SELECTED = 1'b?;
 
always @(*)
casez( { lo_byte_if_i, wb_hi_sel_i, state } )
{ 1'b0, 4'b0011, STATE_PASS_THROUGH }: word_enable = WORD_0_ENABLED;
{ 1'b0, 4'b1100, STATE_PASS_THROUGH }: word_enable = WORD_1_ENABLED;
{ 1'b0, 4'b0001, STATE_PASS_THROUGH }: word_enable = WORD_0_ENABLED;
{ 1'b0, 4'b0010, STATE_PASS_THROUGH }: word_enable = WORD_0_ENABLED;
{ 1'b0, 4'b0100, STATE_PASS_THROUGH }: word_enable = WORD_1_ENABLED;
{ 1'b0, 4'b1000, STATE_PASS_THROUGH }: word_enable = WORD_1_ENABLED;
{ 1'b0, 4'b1111, STATE_PASS_THROUGH }: word_enable = WORD_0_ENABLED;
{ 1'b0, 4'b1111, STATE_1_MORE_CHUNK }: word_enable = WORD_1_ENABLED;
{ 1'b1, 4'b????, STATE_DONT_CARE }: word_enable = WORD_N_ENABLED;
default: word_enable = WORD_N_ENABLED;
endcase
 
always @(*)
case( word_enable )
WORD_0_ENABLED: word_select = WORD_0_SELECTED;
WORD_1_ENABLED: word_select = WORD_1_SELECTED;
default: word_select = 1'bx;
endcase
 
// --------------------------------------------------------------------
// write mux
reg [1:0] byte_write_mux_enc;
always @(*)
casez( {lo_byte_if_i, byte_select, word_select} )
{ 1'b1, BYTE_0_SELECTED, WORD_X_SELECTED }: byte_write_mux_enc = 2'b00;
{ 1'b1, BYTE_1_SELECTED, WORD_X_SELECTED }: byte_write_mux_enc = 2'b01;
{ 1'b1, BYTE_2_SELECTED, WORD_X_SELECTED }: byte_write_mux_enc = 2'b10;
{ 1'b1, BYTE_3_SELECTED, WORD_X_SELECTED }: byte_write_mux_enc = 2'b11;
{ 1'b0, BYTE_X_SELECTED, WORD_0_SELECTED }: byte_write_mux_enc = 2'b00;
{ 1'b0, BYTE_X_SELECTED, WORD_1_SELECTED }: byte_write_mux_enc = 2'b10;
default: byte_write_mux_enc = 2'b00;
endcase
reg [7:0] byte_write_mux;
 
always @(*)
case( byte_write_mux_enc )
2'b00: byte_write_mux = wb_hi_dat_i[7:0];
2'b01: byte_write_mux = wb_hi_dat_i[15:8];
2'b10: byte_write_mux = wb_hi_dat_i[23:16];
2'b11: byte_write_mux = wb_hi_dat_i[31:24];
default: byte_write_mux = wb_hi_dat_i[7:0];
endcase
reg [7:0] word_write_mux;
 
always @(*)
case( word_select )
WORD_0_SELECTED: word_write_mux = wb_hi_dat_i[15:8];
WORD_1_SELECTED: word_write_mux = wb_hi_dat_i[31:24];
default: word_write_mux = wb_hi_dat_i[15:8];
endcase
// --------------------------------------------------------------------
// read buffer & bypass mux
// low side input mux
wire [7:0] read_word_lo_mux = wb_lo_dat_i[7:0];
wire [7:0] read_word_hi_mux = ( word_enable[0] | word_enable[1] )? wb_lo_dat_i[15:8] : wb_lo_dat_i[7:0];
reg [31:0] read_buffer;
wire read_buffer_0_enable = (byte_enable[0] | word_enable[0]) & ~wb_hi_we_i;
wire read_buffer_1_enable = (byte_enable[1] | word_enable[0]) & ~wb_hi_we_i;
wire read_buffer_2_enable = (byte_enable[2] | word_enable[1]) & ~wb_hi_we_i;
wire read_buffer_3_enable = (byte_enable[3] | word_enable[1]) & ~wb_hi_we_i;
always @(posedge wb_hi_clk_i)
if( read_buffer_0_enable )
read_buffer[7:0] <= read_word_lo_mux;
always @(posedge wb_hi_clk_i)
if( read_buffer_1_enable )
read_buffer[15:8] <= read_word_hi_mux;
always @(posedge wb_hi_clk_i)
if( read_buffer_2_enable )
read_buffer[23:16] <= read_word_lo_mux;
always @(posedge wb_hi_clk_i)
if( read_buffer_3_enable )
read_buffer[31:24] <= read_word_hi_mux;
wire [31:0] read_buffer_mux;
// bypass read mux
assign read_buffer_mux[7:0] = read_buffer_0_enable ? read_word_lo_mux : read_buffer[7:0];
assign read_buffer_mux[15:8] = read_buffer_1_enable ? read_word_hi_mux : read_buffer[15:8];
assign read_buffer_mux[23:16] = read_buffer_2_enable ? read_word_lo_mux : read_buffer[23:16];
assign read_buffer_mux[31:24] = read_buffer_3_enable ? read_word_hi_mux : read_buffer[31:24];
// --------------------------------------------------------------------
// misc logic
wire [1:0] lo_addr_bits;
assign lo_addr_bits = ( |byte_enable ) ? byte_select : { word_select, 1'b0 };
wire all_done = ( ~(|state_enc) & (state == STATE_PASS_THROUGH) ) |
( |state_enc & (state == STATE_1_MORE_CHUNK) );
reg [1:0] wb_lo_sel_r;
always @(*)
casez( { lo_byte_if_i, wb_hi_sel_i, state } )
{ 1'b0, 4'b0001, STATE_PASS_THROUGH }: wb_lo_sel_r = 2'b01;
{ 1'b0, 4'b0010, STATE_PASS_THROUGH }: wb_lo_sel_r = 2'b10;
{ 1'b0, 4'b0100, STATE_PASS_THROUGH }: wb_lo_sel_r = 2'b01;
{ 1'b0, 4'b1000, STATE_PASS_THROUGH }: wb_lo_sel_r = 2'b10;
default: wb_lo_sel_r = 2'b11;
endcase
 
// --------------------------------------------------------------------
// output port assignments
assign wb_hi_dat_o = read_buffer_mux;
assign wb_hi_err_o = (wb_lo_err_i | state_enc_error) & wb_hi_stb_i & wb_hi_cyc_i;
assign wb_hi_rty_o = wb_lo_rty_i;
assign wb_hi_ack_o = all_done & wb_hi_stb_i & wb_hi_cyc_i & wb_lo_ack_i;
assign wb_lo_adr_o = { wb_hi_adr_i[31:2], lo_addr_bits };
assign wb_lo_clk_o = wb_hi_clk_i;
assign wb_lo_rst_o = wb_hi_rst_i;
assign wb_lo_cyc_o = wb_hi_cyc_i;
assign wb_lo_stb_o = wb_hi_stb_i;
assign wb_lo_we_o = wb_hi_we_i & wb_hi_stb_i & wb_hi_cyc_i;
assign wb_lo_dat_o = {word_write_mux, byte_write_mux};
assign wb_lo_sel_o = wb_lo_sel_r;
 
endmodule
 
 
/trunk/src/asram_if.v
1,83 → 1,105
//
//
//
 
module asram_if(
inout [15:0] sram_dq, // SRAM Data bus 16 Bits
output [17:0] sram_addr, // SRAM Address bus 18 Bits
output sram_ub_n, // SRAM High-byte Data Mask
output sram_lb_n, // SRAM Low-byte Data Mask
output sram_we_n, // SRAM Write Enable
output sram_ce_n, // SRAM Chip Enable
output sram_oe_n, // SRAM Output Enable
input wb_clk_i, // WISHBONE interface
input wb_rst_i,
input [18:0] wb_adr_i,
input [31:0] wb_dat_i,
input wb_we_i,
input wb_stb_i,
input wb_cyc_i,
input [3:0] wb_sel_i,
output [31:0] wb_dat_o,
output wb_ack_o
);
 
//---------------------------------------------------
// wb_size_bridge
wire [15:0] wb_lo_dat_o;
wire [31:0] wb_lo_adr_o;
wire wb_lo_cyc_o;
wire wb_lo_stb_o;
wire wb_lo_we_o;
wire [1:0] wb_lo_sel_o;
wire wb_lo_ack_i = 1'b1;
wire wb_lo_err_i = 1'b0;
wire wb_lo_rty_i = 1'b0;
wb_size_bridge i_wb_size_bridge(
.wb_hi_clk_i(wb_clk_i),
.wb_hi_rst_i(wb_rst_i),
.wb_hi_dat_o(wb_dat_o),
.wb_hi_dat_i(wb_dat_i),
.wb_hi_adr_i( {13'h0000, wb_adr_i} ),
.wb_hi_cyc_i(wb_cyc_i),
.wb_hi_stb_i(wb_stb_i),
.wb_hi_we_i(wb_we_i),
.wb_hi_sel_i(wb_sel_i),
.wb_hi_ack_o(wb_ack_o),
.wb_hi_err_o(),
.wb_hi_rty_o(),
.wb_lo_clk_o(),
.wb_lo_rst_o(),
.wb_lo_dat_i(sram_dq),
.wb_lo_dat_o(wb_lo_dat_o),
.wb_lo_adr_o(wb_lo_adr_o),
.wb_lo_cyc_o(wb_lo_cyc_o),
.wb_lo_stb_o(wb_lo_stb_o),
.wb_lo_we_o(wb_lo_we_o),
.wb_lo_sel_o(wb_lo_sel_o),
.wb_lo_ack_i(wb_lo_ack_i),
.wb_lo_err_i(wb_lo_err_i),
.wb_lo_rty_i(wb_lo_rty_i),
.lo_byte_if_i(1'b0)
);
//---------------------------------------------------
// outputs
assign sram_dq = wb_lo_we_o ? wb_lo_dat_o : 16'hzz;
assign sram_addr = wb_lo_adr_o[18:1];
assign sram_ub_n = ~wb_lo_sel_o[1];
assign sram_lb_n = ~wb_lo_sel_o[0];
assign sram_we_n = ~wb_lo_we_o;
// assign sram_ce_n = ~(wb_lo_stb_o & wb_lo_cyc_o);
assign sram_ce_n = 1'b0;
assign sram_oe_n = wb_lo_we_o;
endmodule
 
 
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
//// ////
//// 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, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
 
module asram_if(
inout [15:0] sram_dq, // SRAM Data bus 16 Bits
output [17:0] sram_addr, // SRAM Address bus 18 Bits
output sram_ub_n, // SRAM High-byte Data Mask
output sram_lb_n, // SRAM Low-byte Data Mask
output sram_we_n, // SRAM Write Enable
output sram_ce_n, // SRAM Chip Enable
output sram_oe_n, // SRAM Output Enable
input wb_clk_i, // WISHBONE interface
input wb_rst_i,
input [18:0] wb_adr_i,
input [31:0] wb_dat_i,
input wb_we_i,
input wb_stb_i,
input wb_cyc_i,
input [3:0] wb_sel_i,
output [31:0] wb_dat_o,
output wb_ack_o
);
 
//---------------------------------------------------
// wb_size_bridge
wire [15:0] wb_lo_dat_o;
wire [31:0] wb_lo_adr_o;
wire wb_lo_cyc_o;
wire wb_lo_stb_o;
wire wb_lo_we_o;
wire [1:0] wb_lo_sel_o;
wire wb_lo_ack_i = 1'b1;
wire wb_lo_err_i = 1'b0;
wire wb_lo_rty_i = 1'b0;
wb_size_bridge i_wb_size_bridge(
.wb_hi_clk_i(wb_clk_i),
.wb_hi_rst_i(wb_rst_i),
.wb_hi_dat_o(wb_dat_o),
.wb_hi_dat_i(wb_dat_i),
.wb_hi_adr_i( {13'h0000, wb_adr_i} ),
.wb_hi_cyc_i(wb_cyc_i),
.wb_hi_stb_i(wb_stb_i),
.wb_hi_we_i(wb_we_i),
.wb_hi_sel_i(wb_sel_i),
.wb_hi_ack_o(wb_ack_o),
.wb_hi_err_o(),
.wb_hi_rty_o(),
.wb_lo_clk_o(),
.wb_lo_rst_o(),
.wb_lo_dat_i(sram_dq),
.wb_lo_dat_o(wb_lo_dat_o),
.wb_lo_adr_o(wb_lo_adr_o),
.wb_lo_cyc_o(wb_lo_cyc_o),
.wb_lo_stb_o(wb_lo_stb_o),
.wb_lo_we_o(wb_lo_we_o),
.wb_lo_sel_o(wb_lo_sel_o),
.wb_lo_ack_i(wb_lo_ack_i),
.wb_lo_err_i(wb_lo_err_i),
.wb_lo_rty_i(wb_lo_rty_i),
.lo_byte_if_i(1'b0)
);
//---------------------------------------------------
// outputs
assign sram_dq = wb_lo_we_o ? wb_lo_dat_o : 16'hzz;
assign sram_addr = wb_lo_adr_o[18:1];
assign sram_ub_n = ~wb_lo_sel_o[1];
assign sram_lb_n = ~wb_lo_sel_o[0];
assign sram_we_n = ~wb_lo_we_o;
assign sram_ce_n = 1'b0;
assign sram_oe_n = wb_lo_we_o;
endmodule
 
 
/trunk/src/async_mem_if.v
1,253 → 1,275
//
//
//
 
 
module async_mem_if( async_dq, async_addr, async_ub_n, async_lb_n,
async_we_n, async_ce_n, async_oe_n,
wb_clk_i, wb_rst_i, wb_adr_i, wb_dat_i,
wb_we_i, wb_stb_i, wb_cyc_i, wb_sel_i,
wb_dat_o, wb_ack_o,
ce_setup, op_hold, ce_hold,
big_endian_if_i, lo_byte_if_i
);
 
parameter AW = 32;
parameter DW = 8;
 
inout [(DW-1):0] async_dq;
output [(AW-1):0] async_addr;
output async_ub_n;
output async_lb_n;
output async_we_n;
output async_ce_n;
output async_oe_n;
input wb_clk_i;
input wb_rst_i;
input [31:0] wb_adr_i;
input [31:0] wb_dat_i;
input wb_we_i;
input wb_stb_i;
input wb_cyc_i;
input [3:0] wb_sel_i;
output [31:0] wb_dat_o;
output wb_ack_o;
input [3:0] ce_setup;
input [3:0] op_hold; // do not set to zero.
input [3:0] ce_hold;
input big_endian_if_i;
input lo_byte_if_i;
 
 
//---------------------------------------------------
// big endian bridge
 
wire [31:0] beb_wb_dat_i;
assign beb_wb_dat_i[7:0] = big_endian_if_i ? wb_dat_i[31:24] : wb_dat_i[7:0];
assign beb_wb_dat_i[15:8] = big_endian_if_i ? wb_dat_i[23:16] : wb_dat_i[15:8];
assign beb_wb_dat_i[23:16] = big_endian_if_i ? wb_dat_i[15:8] : wb_dat_i[23:16];
assign beb_wb_dat_i[31:24] = big_endian_if_i ? wb_dat_i[7:0] : wb_dat_i[31:24];
 
wire [31:0] beb_wb_dat_o;
assign wb_dat_o[7:0] = big_endian_if_i ? beb_wb_dat_o[31:24] : beb_wb_dat_o[7:0];
assign wb_dat_o[15:8] = big_endian_if_i ? beb_wb_dat_o[23:16] : beb_wb_dat_o[15:8];
assign wb_dat_o[23:16] = big_endian_if_i ? beb_wb_dat_o[15:8] : beb_wb_dat_o[23:16];
assign wb_dat_o[31:24] = big_endian_if_i ? beb_wb_dat_o[7:0] : beb_wb_dat_o[31:24];
 
wire [3:0] beb_wb_sel_i;
assign beb_wb_sel_i[0] = big_endian_if_i ? wb_sel_i[3] : wb_sel_i[0];
assign beb_wb_sel_i[1] = big_endian_if_i ? wb_sel_i[2] : wb_sel_i[1];
assign beb_wb_sel_i[2] = big_endian_if_i ? wb_sel_i[1] : wb_sel_i[2];
assign beb_wb_sel_i[3] = big_endian_if_i ? wb_sel_i[0] : wb_sel_i[3];
 
 
//---------------------------------------------------
// wb_size_bridge
wire [15:0] wb_lo_dat_o;
wire [15:0] wb_lo_dat_i;
wire [31:0] wb_lo_adr_o;
wire wb_lo_cyc_o;
wire wb_lo_stb_o;
wire wb_lo_we_o;
wire [1:0] wb_lo_sel_o;
wire wb_lo_ack_i;
wire wb_lo_err_i = 1'b0;
wire wb_lo_rty_i = 1'b0;
 
 
wb_size_bridge i_wb_size_bridge(
.wb_hi_clk_i(wb_clk_i),
.wb_hi_rst_i(wb_rst_i),
.wb_hi_dat_o(beb_wb_dat_o),
.wb_hi_dat_i(beb_wb_dat_i),
.wb_hi_adr_i( wb_adr_i ),
.wb_hi_cyc_i(wb_cyc_i),
.wb_hi_stb_i(wb_stb_i),
.wb_hi_we_i(wb_we_i),
.wb_hi_sel_i(beb_wb_sel_i),
.wb_hi_ack_o(wb_ack_o),
.wb_hi_err_o(),
.wb_hi_rty_o(),
 
.wb_lo_clk_o(),
.wb_lo_rst_o(),
.wb_lo_dat_i(wb_lo_dat_i),
.wb_lo_dat_o(wb_lo_dat_o),
.wb_lo_adr_o(wb_lo_adr_o),
.wb_lo_cyc_o(wb_lo_cyc_o),
.wb_lo_stb_o(wb_lo_stb_o),
.wb_lo_we_o(wb_lo_we_o),
.wb_lo_sel_o(wb_lo_sel_o),
.wb_lo_ack_i(wb_lo_ack_i),
.wb_lo_err_i(wb_lo_err_i),
.wb_lo_rty_i(wb_lo_rty_i),
 
.lo_byte_if_i(lo_byte_if_i)
);
 
 
// --------------------------------------------------------------------
// state machine inputs
 
wire zero_ce_setup = (ce_setup == 4'h0);
wire zero_ce_hold = (ce_hold == 4'h0);
wire wait_for_counter;
 
 
// --------------------------------------------------------------------
// state machine
 
localparam STATE_DONT_CARE = 4'b????;
localparam STATE_IDLE = 4'b0001;
localparam STATE_CE_SETUP = 4'b0010;
localparam STATE_OP_HOLD = 4'b0100;
localparam STATE_CE_HOLD = 4'b1000;
 
reg [3:0] state;
reg [3:0] next_state;
 
always @(posedge wb_clk_i or posedge wb_rst_i)
if(wb_rst_i)
state <= STATE_IDLE;
else
state <= next_state;
 
always @(*)
case( state )
STATE_IDLE: if( wb_stb_i & wb_cyc_i )
if( zero_ce_setup )
next_state = STATE_OP_HOLD;
else
next_state = STATE_CE_SETUP;
else
next_state = STATE_IDLE;
 
STATE_CE_SETUP: if( wait_for_counter )
next_state = STATE_CE_SETUP;
else
next_state = STATE_OP_HOLD;
 
STATE_OP_HOLD: if( wait_for_counter )
next_state = STATE_OP_HOLD;
else
if( zero_ce_hold )
next_state = STATE_IDLE;
else
next_state = STATE_CE_HOLD;
 
STATE_CE_HOLD: if( wait_for_counter )
next_state = STATE_CE_HOLD;
else
next_state = STATE_IDLE;
 
default: next_state = STATE_IDLE;
endcase
 
 
// --------------------------------------------------------------------
// state machine outputs
 
wire assert_ce = (state != STATE_IDLE);
// wire assert_op = (state == STATE_OP_HOLD) | (state == STATE_CE_HOLD);
wire assert_op = (state == STATE_OP_HOLD);
 
assign wb_lo_ack_i = ( (state == STATE_OP_HOLD) & ~wait_for_counter & zero_ce_hold) |
( (state == STATE_CE_HOLD) & ~wait_for_counter );
 
 
//---------------------------------------------------
// async_dq_buffer
reg [(DW-1):0] async_dq_buffer;
wire async_dq_buffer_en = (state == STATE_OP_HOLD);
 
always @(posedge wb_clk_i)
if(async_dq_buffer_en)
async_dq_buffer <= async_dq;
else
async_dq_buffer <= async_dq_buffer;
 
//---------------------------------------------------
// bypass_mux
 
wire bypass_mux_en = (state == STATE_OP_HOLD) & zero_ce_hold;
wire [(DW-1):0] bypass_mux;
 
assign bypass_mux = bypass_mux_en ? async_dq : async_dq_buffer;
 
 
// --------------------------------------------------------------------
// wait counter mux
reg [3:0] counter_mux;
 
always @(*)
case( next_state )
STATE_CE_SETUP: counter_mux = ce_setup;
STATE_OP_HOLD: counter_mux = op_hold;
STATE_CE_HOLD: counter_mux = ce_hold;
default: counter_mux = 4'bxxxx;
endcase
 
 
// --------------------------------------------------------------------
// wait counter
reg [3:0] counter;
wire counter_load = ~(state == next_state);
 
always @(posedge wb_clk_i)
if( counter_load )
counter <= counter_mux - 1'b1;
else
counter <= counter - 1'b1;
 
assign wait_for_counter = (counter != 4'h0);
 
 
//---------------------------------------------------
// outputs
 
generate
if( DW == 16 )
begin
assign async_dq = wb_lo_we_o ? wb_lo_dat_o : 16'hzz;
assign async_addr = wb_lo_adr_o[AW:1];
assign wb_lo_dat_i = bypass_mux;
end
else
begin
assign async_dq = wb_lo_we_o ? wb_lo_dat_o : 8'hz;
assign async_addr = wb_lo_adr_o[(AW-1):0];
assign wb_lo_dat_i = {8'h00, bypass_mux};
end
endgenerate
 
assign async_ub_n = ~wb_lo_sel_o[1];
assign async_lb_n = ~wb_lo_sel_o[0];
assign async_we_n = ~( wb_lo_we_o & assert_op );
assign async_ce_n = ~( wb_stb_i & wb_cyc_i & assert_ce );
assign async_oe_n = ~( ~wb_lo_we_o & assert_op );
 
 
endmodule
 
 
//////////////////////////////////////////////////////////////////////
//// ////
//// Copyright (C) 2009 Authors and OPENCORES.ORG ////
//// ////
//// 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, download it ////
//// from http://www.opencores.org/lgpl.shtml ////
//// ////
//////////////////////////////////////////////////////////////////////
 
 
module async_mem_if( async_dq, async_addr, async_ub_n, async_lb_n,
async_we_n, async_ce_n, async_oe_n,
wb_clk_i, wb_rst_i, wb_adr_i, wb_dat_i,
wb_we_i, wb_stb_i, wb_cyc_i, wb_sel_i,
wb_dat_o, wb_ack_o,
ce_setup, op_hold, ce_hold,
big_endian_if_i, lo_byte_if_i
);
 
parameter AW = 32;
parameter DW = 8;
 
inout [(DW-1):0] async_dq;
output [(AW-1):0] async_addr;
output async_ub_n;
output async_lb_n;
output async_we_n;
output async_ce_n;
output async_oe_n;
input wb_clk_i;
input wb_rst_i;
input [31:0] wb_adr_i;
input [31:0] wb_dat_i;
input wb_we_i;
input wb_stb_i;
input wb_cyc_i;
input [3:0] wb_sel_i;
output [31:0] wb_dat_o;
output wb_ack_o;
input [3:0] ce_setup;
input [3:0] op_hold; // do not set to zero.
input [3:0] ce_hold;
input big_endian_if_i;
input lo_byte_if_i;
 
 
//---------------------------------------------------
// big endian bridge
 
wire [31:0] beb_wb_dat_i;
assign beb_wb_dat_i[7:0] = big_endian_if_i ? wb_dat_i[31:24] : wb_dat_i[7:0];
assign beb_wb_dat_i[15:8] = big_endian_if_i ? wb_dat_i[23:16] : wb_dat_i[15:8];
assign beb_wb_dat_i[23:16] = big_endian_if_i ? wb_dat_i[15:8] : wb_dat_i[23:16];
assign beb_wb_dat_i[31:24] = big_endian_if_i ? wb_dat_i[7:0] : wb_dat_i[31:24];
 
wire [31:0] beb_wb_dat_o;
assign wb_dat_o[7:0] = big_endian_if_i ? beb_wb_dat_o[31:24] : beb_wb_dat_o[7:0];
assign wb_dat_o[15:8] = big_endian_if_i ? beb_wb_dat_o[23:16] : beb_wb_dat_o[15:8];
assign wb_dat_o[23:16] = big_endian_if_i ? beb_wb_dat_o[15:8] : beb_wb_dat_o[23:16];
assign wb_dat_o[31:24] = big_endian_if_i ? beb_wb_dat_o[7:0] : beb_wb_dat_o[31:24];
 
wire [3:0] beb_wb_sel_i;
assign beb_wb_sel_i[0] = big_endian_if_i ? wb_sel_i[3] : wb_sel_i[0];
assign beb_wb_sel_i[1] = big_endian_if_i ? wb_sel_i[2] : wb_sel_i[1];
assign beb_wb_sel_i[2] = big_endian_if_i ? wb_sel_i[1] : wb_sel_i[2];
assign beb_wb_sel_i[3] = big_endian_if_i ? wb_sel_i[0] : wb_sel_i[3];
 
 
//---------------------------------------------------
// wb_size_bridge
wire [15:0] wb_lo_dat_o;
wire [15:0] wb_lo_dat_i;
wire [31:0] wb_lo_adr_o;
wire wb_lo_cyc_o;
wire wb_lo_stb_o;
wire wb_lo_we_o;
wire [1:0] wb_lo_sel_o;
wire wb_lo_ack_i;
wire wb_lo_err_i = 1'b0;
wire wb_lo_rty_i = 1'b0;
 
 
wb_size_bridge i_wb_size_bridge(
.wb_hi_clk_i(wb_clk_i),
.wb_hi_rst_i(wb_rst_i),
.wb_hi_dat_o(beb_wb_dat_o),
.wb_hi_dat_i(beb_wb_dat_i),
.wb_hi_adr_i( wb_adr_i ),
.wb_hi_cyc_i(wb_cyc_i),
.wb_hi_stb_i(wb_stb_i),
.wb_hi_we_i(wb_we_i),
.wb_hi_sel_i(beb_wb_sel_i),
.wb_hi_ack_o(wb_ack_o),
.wb_hi_err_o(),
.wb_hi_rty_o(),
 
.wb_lo_clk_o(),
.wb_lo_rst_o(),
.wb_lo_dat_i(wb_lo_dat_i),
.wb_lo_dat_o(wb_lo_dat_o),
.wb_lo_adr_o(wb_lo_adr_o),
.wb_lo_cyc_o(wb_lo_cyc_o),
.wb_lo_stb_o(wb_lo_stb_o),
.wb_lo_we_o(wb_lo_we_o),
.wb_lo_sel_o(wb_lo_sel_o),
.wb_lo_ack_i(wb_lo_ack_i),
.wb_lo_err_i(wb_lo_err_i),
.wb_lo_rty_i(wb_lo_rty_i),
 
.lo_byte_if_i(lo_byte_if_i)
);
 
 
// --------------------------------------------------------------------
// state machine inputs
 
wire zero_ce_setup = (ce_setup == 4'h0);
wire zero_ce_hold = (ce_hold == 4'h0);
wire wait_for_counter;
 
 
// --------------------------------------------------------------------
// state machine
 
localparam STATE_DONT_CARE = 4'b????;
localparam STATE_IDLE = 4'b0001;
localparam STATE_CE_SETUP = 4'b0010;
localparam STATE_OP_HOLD = 4'b0100;
localparam STATE_CE_HOLD = 4'b1000;
 
reg [3:0] state;
reg [3:0] next_state;
 
always @(posedge wb_clk_i or posedge wb_rst_i)
if(wb_rst_i)
state <= STATE_IDLE;
else
state <= next_state;
 
always @(*)
case( state )
STATE_IDLE: if( wb_stb_i & wb_cyc_i )
if( zero_ce_setup )
next_state = STATE_OP_HOLD;
else
next_state = STATE_CE_SETUP;
else
next_state = STATE_IDLE;
 
STATE_CE_SETUP: if( wait_for_counter )
next_state = STATE_CE_SETUP;
else
next_state = STATE_OP_HOLD;
 
STATE_OP_HOLD: if( wait_for_counter )
next_state = STATE_OP_HOLD;
else
if( zero_ce_hold )
next_state = STATE_IDLE;
else
next_state = STATE_CE_HOLD;
 
STATE_CE_HOLD: if( wait_for_counter )
next_state = STATE_CE_HOLD;
else
next_state = STATE_IDLE;
 
default: next_state = STATE_IDLE;
endcase
 
 
// --------------------------------------------------------------------
// state machine outputs
 
wire assert_ce = (state != STATE_IDLE);
wire assert_op = (state == STATE_OP_HOLD);
 
assign wb_lo_ack_i = ( (state == STATE_OP_HOLD) & ~wait_for_counter & zero_ce_hold) |
( (state == STATE_CE_HOLD) & ~wait_for_counter );
 
 
//---------------------------------------------------
// async_dq_buffer
reg [(DW-1):0] async_dq_buffer;
wire async_dq_buffer_en = (state == STATE_OP_HOLD);
 
always @(posedge wb_clk_i)
if(async_dq_buffer_en)
async_dq_buffer <= async_dq;
else
async_dq_buffer <= async_dq_buffer;
 
//---------------------------------------------------
// bypass_mux
 
wire bypass_mux_en = (state == STATE_OP_HOLD) & zero_ce_hold;
wire [(DW-1):0] bypass_mux;
 
assign bypass_mux = bypass_mux_en ? async_dq : async_dq_buffer;
 
 
// --------------------------------------------------------------------
// wait counter mux
reg [3:0] counter_mux;
 
always @(*)
case( next_state )
STATE_CE_SETUP: counter_mux = ce_setup;
STATE_OP_HOLD: counter_mux = op_hold;
STATE_CE_HOLD: counter_mux = ce_hold;
default: counter_mux = 4'bxxxx;
endcase
 
 
// --------------------------------------------------------------------
// wait counter
reg [3:0] counter;
wire counter_load = ~(state == next_state);
 
always @(posedge wb_clk_i)
if( counter_load )
counter <= counter_mux - 1'b1;
else
counter <= counter - 1'b1;
 
assign wait_for_counter = (counter != 4'h0);
 
 
//---------------------------------------------------
// outputs
 
generate
if( DW == 16 )
begin
assign async_dq = wb_lo_we_o ? wb_lo_dat_o : 16'hzz;
assign async_addr = wb_lo_adr_o[AW:1];
assign wb_lo_dat_i = bypass_mux;
end
else
begin
assign async_dq = wb_lo_we_o ? wb_lo_dat_o : 8'hz;
assign async_addr = wb_lo_adr_o[(AW-1):0];
assign wb_lo_dat_i = {8'h00, bypass_mux};
end
endgenerate
 
assign async_ub_n = ~wb_lo_sel_o[1];
assign async_lb_n = ~wb_lo_sel_o[0];
assign async_we_n = ~( wb_lo_we_o & assert_op );
assign async_ce_n = ~( wb_stb_i & wb_cyc_i & assert_ce );
assign async_oe_n = ~( ~wb_lo_we_o & assert_op );
 
 
endmodule
 
 

powered by: WebSVN 2.1.0

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