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

Subversion Repositories spi

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 8 to Rev 9
    Reverse comparison

Rev 8 → Rev 9

/trunk/bench/verilog/tb_spi_top.v
64,14 → 64,21
wire miso;
 
reg [31:0] q;
reg [31:0] q1;
reg [31:0] q2;
reg [31:0] q3;
 
parameter SPI_RX_L = 5'h0;
parameter SPI_RX_H = 5'h4;
parameter SPI_TX_L = 5'h0;
parameter SPI_TX_H = 5'h4;
parameter SPI_CTRL = 5'h8;
parameter SPI_DEVIDE = 5'hc;
parameter SPI_SS = 5'h10;
parameter SPI_RX_0 = 5'h0;
parameter SPI_RX_1 = 5'h4;
parameter SPI_RX_2 = 5'h8;
parameter SPI_RX_3 = 5'hc;
parameter SPI_TX_0 = 5'h0;
parameter SPI_TX_1 = 5'h4;
parameter SPI_TX_2 = 5'h8;
parameter SPI_TX_3 = 5'hc;
parameter SPI_CTRL = 5'h10;
parameter SPI_DIVIDE = 5'h14;
parameter SPI_SS = 5'h18;
 
// Generate clock
always #5 clk = ~clk;
123,24 → 130,26
@(posedge clk);
 
// Program core
i_wb_master.wb_write(0, SPI_DEVIDE, 32'h05); // set devider register
i_wb_master.wb_write(0, SPI_TX_L, 32'h5a); // set tx register to 0x5a
i_wb_master.wb_write(0, SPI_CTRL, 32'h40); // set 8 bit transfer
i_wb_master.wb_write(0, SPI_DIVIDE, 32'h00); // set devider register
i_wb_master.wb_write(0, SPI_TX_0, 32'h5a); // set tx register to 0x5a
i_wb_master.wb_write(0, SPI_CTRL, 32'h42); // set 8 bit transfer
i_wb_master.wb_write(0, SPI_SS, 32'h01); // set ss 0
 
$display("status: %t programmed registers", $time);
 
i_wb_master.wb_cmp(0, SPI_DEVIDE, 32'h05); // verify devider register
i_wb_master.wb_cmp(0, SPI_TX_L, 32'h5a); // verify tx register
i_wb_master.wb_cmp(0, SPI_CTRL, 32'h40); // verify tx register
i_wb_master.wb_cmp(0, SPI_DIVIDE, 32'h05); // verify devider register
i_wb_master.wb_cmp(0, SPI_TX_0, 32'h5a); // verify tx register
i_wb_master.wb_cmp(0, SPI_CTRL, 32'h42); // verify tx register
i_wb_master.wb_cmp(0, SPI_SS, 32'h01); // verify ss register
 
$display("status: %t verified registers", $time);
 
i_spi_slave.rx_negedge = 1'b1;
i_wb_master.wb_write(0, SPI_CTRL, 32'h41); // set 8 bit transfer, start transfer
i_spi_slave.tx_negedge = 1'b0;
i_spi_slave.data[31:0] = 32'ha5967e5a;
i_wb_master.wb_write(0, SPI_CTRL, 32'h43); // set 8 bit transfer, start transfer
 
$display("status: %t generate transfer: 8 bit (0x0000005a), msb first, tx posedge, rx negedge", $time);
$display("status: %t generate transfer: 8 bit, msb first, tx posedge, rx negedge", $time);
 
// Check bsy bit
i_wb_master.wb_read(0, SPI_CTRL, q);
147,17 → 156,20
while (q[0])
i_wb_master.wb_read(1, SPI_CTRL, q);
 
if (i_spi_slave.data == 32'h5a)
$display("status: %t transfer completed: 0x0000005a == 0x%x ok", $time, i_spi_slave.data);
i_wb_master.wb_read(1, SPI_RX_0, q);
 
if (i_spi_slave.data[7:0] == 8'h5a && q == 32'h000000a5)
$display("status: %t transfer completed: ok", $time);
else
$display("status: %t transfer completed: 0x0000005a != 0x%x nok", $time, i_spi_slave.data);
$display("status: %t transfer completed: nok", $time);
 
i_spi_slave.rx_negedge = 1'b0;
i_wb_master.wb_write(0, SPI_TX_L, 32'ha5);
i_spi_slave.tx_negedge = 1'b1;
i_wb_master.wb_write(0, SPI_TX_0, 32'ha5);
i_wb_master.wb_write(0, SPI_CTRL, 32'h44); // set 8 bit transfer, tx negedge
i_wb_master.wb_write(0, SPI_CTRL, 32'h45); // set 8 bit transfer, tx negedge, start transfer
 
$display("status: %t generate transfer: 8 bit (0x0000005a), msb first, tx negedge, rx posedge", $time);
$display("status: %t generate transfer: 8 bit, msb first, tx negedge, rx posedge", $time);
 
// Check bsy bit
i_wb_master.wb_read(0, SPI_CTRL, q);
164,36 → 176,20
while (q[0])
i_wb_master.wb_read(1, SPI_CTRL, q);
 
if (i_spi_slave.data == 32'h5aa5)
$display("status: %t transfer completed: 0x00005aa5 == 0x%x ok", $time, i_spi_slave.data);
else
$display("status: %t transfer completed: 0x00005aa5 != 0x%x nok", $time, i_spi_slave.data);
i_wb_master.wb_read(1, SPI_RX_0, q);
 
i_spi_slave.rx_negedge = 1'b0;
i_wb_master.wb_write(0, SPI_TX_L, 32'h5aa5);
i_wb_master.wb_write(0, SPI_CTRL, 32'h284); // set 16 bit transfer, tx negedge, lsb
i_wb_master.wb_write(0, SPI_CTRL, 32'h285); // set 16 bit transfer, tx negedge, start transfer
 
$display("status: %t generate transfer: 16 bit (0x00005aa5), lsb first, tx negedge, rx posedge", $time);
 
// Check bsy bit
i_wb_master.wb_read(0, SPI_CTRL, q);
while (q[0])
i_wb_master.wb_read(1, SPI_CTRL, q);
 
 
if (i_spi_slave.data == 32'h5aa5a55a)
$display("status: %t transfer completed: 0x5aa5a55a == 0x%x ok", $time, i_spi_slave.data);
if (i_spi_slave.data[7:0] == 8'ha5 && q == 32'h00000096)
$display("status: %t transfer completed: ok", $time);
else
$display("status: %t transfer completed: 0x5aa5a55a != 0x%x nok", $time, i_spi_slave.data);
$display("status: %t transfer completed: nok", $time);
 
i_spi_slave.rx_negedge = 1'b0;
i_spi_slave.tx_negedge = 1'b1;
i_wb_master.wb_write(0, SPI_TX_L, 32'h55);
i_wb_master.wb_write(0, SPI_CTRL, 32'h244); // set 8 bit transfer, tx negedge, lsb
i_wb_master.wb_write(0, SPI_CTRL, 32'h245); // set 8 bit transfer, tx negedge, start transfer
i_wb_master.wb_write(0, SPI_TX_0, 32'h5aa5);
i_wb_master.wb_write(0, SPI_CTRL, 32'h484); // set 16 bit transfer, tx negedge, lsb
i_wb_master.wb_write(0, SPI_CTRL, 32'h485); // set 16 bit transfer, tx negedge, start transfer
 
$display("status: %t generate transfer: 8 bit (0x000000a5), lsb first, tx negedge, rx posedge", $time);
$display("status: %t generate transfer: 16 bit, lsb first, tx negedge, rx posedge", $time);
 
// Check bsy bit
i_wb_master.wb_read(0, SPI_CTRL, q);
200,24 → 196,21
while (q[0])
i_wb_master.wb_read(1, SPI_CTRL, q);
 
i_wb_master.wb_read(1, SPI_RX_L, q);
i_wb_master.wb_read(1, SPI_RX_0, q);
 
if (i_spi_slave.data == 32'ha5a55aaa && q == 32'h0000005a)
$display("status: %t transfer completed: 0xa5a55aaa == 0x%x 0x0000005a == 0x%x ok", $time, i_spi_slave.data, q);
else if (i_spi_slave.data == 32'ha5a55aaa)
$display("status: %t transfer completed: 0xa5a55aaa == 0x%x 0x0000005a != 0x%x nok", $time, i_spi_slave.data, q);
else if (q == 32'h0000005a)
$display("status: %t transfer completed: 0xa5a55aaa != 0x%x 0x0000005a == 0x%x nok", $time, i_spi_slave.data, q);
if (i_spi_slave.data[15:0] == 16'ha55a && q == 32'h00005a7e)
$display("status: %t transfer completed: ok", $time);
else
$display("status: %t transfer completed: 0xa5a55aaa != 0x%x 0x0000005a != 0x%x nok", $time, i_spi_slave.data, q);
$display("status: %t transfer completed: nok", $time);
 
i_spi_slave.rx_negedge = 1'b1;
i_spi_slave.tx_negedge = 1'b0;
i_wb_master.wb_write(0, SPI_TX_L, 32'haa);
i_wb_master.wb_write(0, SPI_CTRL, 32'h242); // set 8 bit transfer, rx negedge, lsb
i_wb_master.wb_write(0, SPI_CTRL, 32'h243); // set 8 bit transfer, rx negedge, start transfer
i_wb_master.wb_write(0, SPI_TX_0, 32'h76543210);
i_wb_master.wb_write(0, SPI_TX_1, 32'hfedcba98);
i_wb_master.wb_write(0, SPI_CTRL, 32'h602); // set 64 bit transfer, rx negedge, lsb
i_wb_master.wb_write(0, SPI_CTRL, 32'h603); // set 64 bit transfer, rx negedge, start transfer
 
$display("status: %t generate transfer: 8 bit (0x000000aa), lsb first, tx posedge, rx negedge", $time);
$display("status: %t generate transfer: 64 bit, lsb first, tx posedge, rx negedge", $time);
 
// Check bsy bit
i_wb_master.wb_read(0, SPI_CTRL, q);
224,24 → 217,24
while (q[0])
i_wb_master.wb_read(1, SPI_CTRL, q);
 
i_wb_master.wb_read(1, SPI_RX_L, q);
i_wb_master.wb_read(1, SPI_RX_0, q);
i_wb_master.wb_read(1, SPI_RX_1, q1);
 
if (i_spi_slave.data == 32'ha55aaa55 && q == 32'h000000a5)
$display("status: %t transfer completed: 0xa55aaa55 == 0x%x 0x000000a5 == 0x%x ok", $time, i_spi_slave.data, q);
else if (i_spi_slave.data == 32'ha55aaa55)
$display("status: %t transfer completed: 0xa55aaa55 == 0x%x 0x000000a5 != 0x%x nok", $time, i_spi_slave.data, q);
else if (q == 32'h000000a5)
$display("status: %t transfer completed: 0xa55aaa55 != 0x%x 0x000000a5 == 0x%x nok", $time, i_spi_slave.data, q);
if (i_spi_slave.data == 32'h195d3b7f && q == 32'h5aa5a55a && q1 == 32'h76543210)
$display("status: %t transfer completed: ok", $time);
else
$display("status: %t transfer completed: 0xa55aaa55 != 0x%x 0x000000a5 != 0x%x nok", $time, i_spi_slave.data, q);
$display("status: %t transfer completed: nok", $time);
 
i_spi_slave.rx_negedge = 1'b1;
i_spi_slave.tx_negedge = 1'b0;
i_wb_master.wb_write(0, SPI_TX_L, 32'haa55);
i_wb_master.wb_write(0, SPI_CTRL, 32'h82); // set 16 bit transfer, rx negedge
i_wb_master.wb_write(0, SPI_CTRL, 32'h83); // set 16 bit transfer, rx negedge, start transfer
i_spi_slave.rx_negedge = 1'b0;
i_spi_slave.tx_negedge = 1'b1;
i_wb_master.wb_write(0, SPI_TX_0, 32'hccddeeff);
i_wb_master.wb_write(0, SPI_TX_1, 32'h8899aabb);
i_wb_master.wb_write(0, SPI_TX_2, 32'h44556677);
i_wb_master.wb_write(0, SPI_TX_3, 32'h00112233);
i_wb_master.wb_write(0, SPI_CTRL, 32'h04);
i_wb_master.wb_write(0, SPI_CTRL, 32'h05);
 
$display("status: %t generate transfer: 8 bit (0x0000aa55), msb first, tx posedge, rx negedge", $time);
$display("status: %t generate transfer: 128 bit, msb first, tx posedge, rx negedge", $time);
 
// Check bsy bit
i_wb_master.wb_read(0, SPI_CTRL, q);
248,122 → 241,74
while (q[0])
i_wb_master.wb_read(1, SPI_CTRL, q);
 
i_wb_master.wb_read(1, SPI_RX_L, q);
i_wb_master.wb_read(1, SPI_RX_0, q);
i_wb_master.wb_read(1, SPI_RX_1, q1);
i_wb_master.wb_read(1, SPI_RX_2, q2);
i_wb_master.wb_read(1, SPI_RX_3, q3);
 
if (i_spi_slave.data == 32'haa55aa55 && q == 32'h0000a55a)
$display("status: %t transfer completed: 0xaa55aa55 == 0x%x 0x0000a55a == 0x%x ok", $time, i_spi_slave.data, q);
else if (i_spi_slave.data == 32'haa55aa55)
$display("status: %t transfer completed: 0xaa55aa55 == 0x%x 0x0000a55a != 0x%x nok", $time, i_spi_slave.data, q);
else if (q == 32'h0000a55a)
$display("status: %t transfer completed: 0xaa55aa55 != 0x%x 0x0000a55a == 0x%x nok", $time, i_spi_slave.data, q);
if (i_spi_slave.data == 32'hccddeeff && q == 32'h8899aabb && q1 == 32'h44556677 && q2 == 32'h00112233 && q3 == 32'h195d3b7f)
$display("status: %t transfer completed: ok", $time);
else
$display("status: %t transfer completed: 0xaa55aa55 != 0x%x 0x0000a55a != 0x%x nok", $time, i_spi_slave.data, q);
$display("status: %t transfer completed: nok", $time);
 
i_spi_slave.rx_negedge = 1'b1;
i_spi_slave.rx_negedge = 1'b0;
i_spi_slave.tx_negedge = 1'b1;
i_wb_master.wb_write(0, SPI_TX_L, 32'haa55a5a5);
i_wb_master.wb_write(0, SPI_CTRL, 32'h500); // set 32 bit transfer, ie
i_wb_master.wb_write(0, SPI_CTRL, 32'h501); // set 32 bit transfer, start transfer
i_wb_master.wb_write(0, SPI_TX_0, 32'haa55a5a5);
i_wb_master.wb_write(0, SPI_CTRL, 32'h904);
i_wb_master.wb_write(0, SPI_CTRL, 32'h905);
 
$display("status: %t generate transfer: 32 bit (0xaa55a5a5), msb first, tx negedge, rx negedge", $time);
$display("status: %t generate transfer: 32 bit, msb first, tx negedge, rx posedge, ie", $time);
 
// Check interrupt signal
while (!int)
@(posedge clk);
 
i_wb_master.wb_read(1, SPI_RX_L, q);
i_wb_master.wb_read(1, SPI_RX_0, q);
@(posedge clk);
if (int)
$display("status: %t transfer completed: interrupt still active nok", $time, i_spi_slave.data, q);
 
if (i_spi_slave.data == 32'haa55a5a5 && q == 32'h552ad52a)
$display("status: %t transfer completed: 0xaa55a5a5 == 0x%x 0x552ad52a == 0x%x ok", $time, i_spi_slave.data, q);
else if (i_spi_slave.data == 32'haa55a5a5)
$display("status: %t transfer completed: 0xaa55a5a5 == 0x%x 0x552ad52a != 0x%x nok", $time, i_spi_slave.data, q);
else if (q == 32'h552ad52a)
$display("status: %t transfer completed: 0xaa55a5a5 != 0x%x 0x552ad52a == 0x%x nok", $time, i_spi_slave.data, q);
if (!int && i_spi_slave.data == 32'haa55a5a5 && q == 32'hccddeeff)
$display("status: %t transfer completed: ok", $time);
else
$display("status: %t transfer completed: 0xaa55a5a5 != 0x%x 0x552ad52a != 0x%x nok", $time, i_spi_slave.data, q);
$display("status: %t transfer completed: nok", $time);
 
i_spi_slave.rx_negedge = 1'b0;
i_spi_slave.rx_negedge = 1'b1;
i_spi_slave.tx_negedge = 1'b0;
i_wb_master.wb_write(0, SPI_CTRL, 32'h706); // set 32 bit transfer, ie, lsb, rx negedge, tx negedge
i_wb_master.wb_write(0, SPI_CTRL, 32'h707); // set 32 bit transfer, start transfer
i_wb_master.wb_write(0, SPI_TX_0, 32'h01248421);
i_wb_master.wb_write(0, SPI_CTRL, 32'h1902);
i_wb_master.wb_write(0, SPI_CTRL, 32'h1903);
 
$display("status: %t generate transfer: 32 bit (0xaa55a5a5), msb first, tx negedge, rx negedge", $time);
$display("status: %t generate transfer: 32 bit, msb first, tx posedge, rx negedge, ie, ass", $time);
 
// Check interrupt signal
while (!int)
@(posedge clk);
 
i_wb_master.wb_read(1, SPI_RX_L, q);
i_wb_master.wb_read(1, SPI_RX_0, q);
 
@(posedge clk);
if (int)
$display("status: %t transfer completed: interrupt still active nok", $time, i_spi_slave.data, q);
 
if (i_spi_slave.data == 32'h54ab54aa && q == 32'ha5a5aa55)
$display("status: %t transfer completed: 0x54ab54aa == 0x%x 0xa5a5aa55 == 0x%x ok", $time, i_spi_slave.data, q);
else if (i_spi_slave.data == 32'h54ab54aa)
$display("status: %t transfer completed: 0x54ab54aa == 0x%x 0xa5a5aa55 != 0x%x nok", $time, i_spi_slave.data, q);
else if (q == 32'ha5a5aa55)
$display("status: %t transfer completed: 0x54ab54aa != 0x%x 0xa5a5aa55 == 0x%x nok", $time, i_spi_slave.data, q);
if (!int && i_spi_slave.data == 32'h01248421 && q == 32'haa55a5a5)
$display("status: %t transfer completed: ok", $time);
else
$display("status: %t transfer completed: 0x54ab54aa != 0x%x 0xa5a5aa55 != 0x%x nok", $time, i_spi_slave.data, q);
$display("status: %t transfer completed: nok", $time);
 
i_wb_master.wb_write(0, SPI_TX_L, 32'h01234567);
i_wb_master.wb_write(0, SPI_TX_H, 32'h89abcdef);
i_wb_master.wb_write(0, SPI_CTRL, 32'h606); // set 64 bit transfer, ie, lsb, rx negedge, tx negedge
i_wb_master.wb_write(0, SPI_CTRL, 32'h607); // set 64 bit transfer, start transfer
i_spi_slave.rx_negedge = 1'b1;
i_spi_slave.tx_negedge = 1'b0;
i_wb_master.wb_write(0, SPI_TX_0, 32'h1);
i_wb_master.wb_write(0, SPI_CTRL, 32'h180a);
i_wb_master.wb_write(0, SPI_CTRL, 32'h180b);
 
$display("status: %t generate transfer: 64 bit (0x0123456789abcdef), msb first, tx negedge, rx negedge", $time);
$display("status: %t generate transfer: 1 bit, msb first, tx posedge, rx negedge, ie, ass", $time);
 
// Check interrupt signal
while (!int)
@(posedge clk);
 
i_wb_master.wb_read(1, SPI_RX_H, q);
i_wb_master.wb_read(1, SPI_RX_0, q);
 
@(posedge clk);
if (int)
$display("status: %t transfer completed: interrupt still active nok", $time, i_spi_slave.data, q);
 
if (i_spi_slave.data == 32'hf7b3d591 && q == 32'h01234567)
$display("status: %t transfer completed: 0xf7b3d591 == 0x%x 0x01234567 == 0x%x ok", $time, i_spi_slave.data, q);
else if (i_spi_slave.data == 32'hf7b3d591)
$display("status: %t transfer completed: 0xf7b3d591 == 0x%x 0x01234567 != 0x%x nok", $time, i_spi_slave.data, q);
else if (q == 32'hf7b3d591)
$display("status: %t transfer completed: 0xf7b3d591 != 0x%x 0x01234567 == 0x%x nok", $time, i_spi_slave.data, q);
if (!int && i_spi_slave.data == 32'h02490843 && q == 32'h0)
$display("status: %t transfer completed: ok", $time);
else
$display("status: %t transfer completed: 0xf7b3d591 != 0x%x 0x01234567 != 0x%x nok", $time, i_spi_slave.data, q);
$display("status: %t transfer completed: nok", $time);
 
i_wb_master.wb_write(0, SPI_TX_L, 32'hffeeddcc);
i_wb_master.wb_write(0, SPI_TX_H, 32'hbbaa9988);
i_wb_master.wb_write(0, SPI_CTRL, 32'he06); // ass, set 64 bit transfer, ie, lsb, rx negedge, tx negedge
i_wb_master.wb_write(0, SPI_CTRL, 32'he07); // set 64 bit transfer, start transfer
 
$display("status: %t generate transfer: 64 bit (0xffeeddccbbaa9988), ass, msb first, tx negedge, rx negedge", $time);
 
// Check interrupt signal
while (!int)
@(posedge clk);
 
i_wb_master.wb_read(1, SPI_RX_H, q);
 
@(posedge clk);
if (int)
$display("status: %t transfer completed: interrupt still active nok", $time, i_spi_slave.data, q);
 
if (i_spi_slave.data == 32'h119955dd && q == 32'hffeeddcc)
$display("status: %t transfer completed: 0x119955dd == 0x%x 0xffeeddcc == 0x%x ok", $time, i_spi_slave.data, q);
else if (i_spi_slave.data == 32'h119955dd)
$display("status: %t transfer completed: 0x119955dd == 0x%x 0xffeeddcc != 0x%x nok", $time, i_spi_slave.data, q);
else if (q == 32'h119955dd)
$display("status: %t transfer completed: 0x119955dd != 0x%x 0xffeeddcc == 0x%x nok", $time, i_spi_slave.data, q);
else
$display("status: %t transfer completed: 0x119955dd != 0x%x 0xffeeddcc != 0x%x nok", $time, i_spi_slave.data, q);
 
$display("\n\nstatus: %t Testbench done", $time);
 
#25000; // wait 25us
/trunk/rtl/verilog/spi_top.v
94,8 → 94,7
wire ass; // automatic slave select
wire spi_divider_sel; // divider register select
wire spi_ctrl_sel; // ctrl register select
wire spi_tx_sel_l; // tx_l register select
wire spi_tx_sel_h; // tx_h register select
wire [3:0] spi_tx_sel; // tx_l register select
wire spi_ss_sel; // ss register select
wire tip; // transfer in progress
wire pos_edge; // recognize posedge of sclk
105,8 → 104,10
// Address decoder
assign spi_divider_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_DEVIDE);
assign spi_ctrl_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_CTRL);
assign spi_tx_sel_h = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_H);
assign spi_tx_sel_l = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_L);
assign spi_tx_sel[0] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_0);
assign spi_tx_sel[1] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_1);
assign spi_tx_sel[2] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_2);
assign spi_tx_sel[3] = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_TX_3);
assign spi_ss_sel = wb_cyc_i & wb_stb_i & (wb_adr_i[`SPI_OFS_BITS] == `SPI_SS);
// Read from registers
113,13 → 114,22
always @(wb_adr_i or rx or ctrl or divider or ss)
begin
case (wb_adr_i[`SPI_OFS_BITS])
`ifdef SPI_MAX_CHAR_128
`SPI_RX_0: wb_dat = rx[31:0];
`SPI_RX_1: wb_dat = rx[63:32];
`SPI_RX_2: wb_dat = rx[95:64];
`SPI_RX_3: wb_dat = rx[127:96];
`else
`ifdef SPI_MAX_CHAR_64
`SPI_RX_L: wb_dat = rx[31:0];
`SPI_RX_H: wb_dat = rx[63:32];
`SPI_RX_0: wb_dat = rx[31:0];
`SPI_RX_1: wb_dat = rx[63:32];
`SPI_RX_2: wb_dat = 32'b0;
`SPI_RX_3: wb_dat = 32'b0;
`else
`SPI_RX_L: wb_dat = {{32-`SPI_MAX_CHAR{1'b0}}, rx};
`SPI_RX_H: wb_dat = 32'b0;
`SPI_RX_0: wb_dat = {{32-`SPI_MAX_CHAR{1'b0}}, rx};
`SPI_RX_1: wb_dat = 32'b0;
`endif
`endif
`SPI_CTRL: wb_dat = {{32-`SPI_CTRL_BIT_NB{1'b0}}, ctrl};
`SPI_DEVIDE: wb_dat = {{32-`SPI_DIVIDER_BIT_NB{1'b0}}, divider};
`SPI_SS: wb_dat = {{32-`SPI_SS_NB{1'b0}}, ss};
211,12 → 221,12
assign ss_pad_o = ~((ss & tip & ass) | (ss & !ass));
spi_clgen clgen (.clk_in(wb_clk_i), .rst(wb_rst_i), .enable(tip), .last_clk(last_bit),
spi_clgen clgen (.clk_in(wb_clk_i), .rst(wb_rst_i), .go(go), .enable(tip), .last_clk(last_bit),
.divider(divider), .clk_out(sclk_pad_o), .pos_edge(pos_edge),
.neg_edge(neg_edge));
spi_shift shift (.clk(wb_clk_i), .rst(wb_rst_i), .len(char_len[`SPI_CHAR_LEN_BITS-1:0]),
.latch_h(spi_tx_sel_h && wb_we_i), .latch_l(spi_tx_sel_l && wb_we_i), .lsb(lsb),
.latch(spi_tx_sel[3:0] & {4{wb_we_i}}), .lsb(lsb),
.go(go), .pos_edge(pos_edge), .neg_edge(neg_edge),
.rx_negedge(rx_negedge), .tx_negedge(tx_negedge),
.tip(tip), .last(last_bit),
/trunk/rtl/verilog/spi_clgen.v
41,7 → 41,7
`include "spi_defines.v"
`include "timescale.v"
 
module spi_clgen (clk_in, rst, enable, last_clk, divider, clk_out, pos_edge, neg_edge);
module spi_clgen (clk_in, rst, go, enable, last_clk, divider, clk_out, pos_edge, neg_edge);
 
parameter Tp = 1;
48,6 → 48,7
input clk_in; // input clock (system clock)
input rst; // reset
input enable; // clock enable
input go; // start transfer
input last_clk; // last clock
input [`SPI_DIVIDER_BIT_NB-1:0] divider; // clock divider (output clock is divided by this value)
output clk_out; // output clock
86,7 → 87,7
if(rst)
clk_out <= #Tp 1'b0;
else
clk_out <= #Tp (cnt_zero && (!last_clk || clk_out)) ? ~clk_out : clk_out;
clk_out <= #Tp (enable && cnt_zero && (!last_clk || clk_out)) ? ~clk_out : clk_out;
end
// Pos and neg edge signals
99,8 → 100,8
end
else
begin
pos_edge <= #Tp (clk_out == 1'b0) && cnt_one;
neg_edge <= #Tp (clk_out == 1'b1) && cnt_one;
pos_edge <= #Tp (enable && !clk_out && cnt_one) || (!(|divider) && clk_out) || (!(|divider) && go && !enable);
neg_edge <= #Tp (enable && clk_out && cnt_one) || (!(|divider) && !clk_out && enable);
end
end
endmodule
/trunk/rtl/verilog/spi_defines.v
47,13 → 47,15
 
//
// Maximum nuber of bits that can be send/received at once. Alloved values are
// 64, 32, 16 and 8. SPI_CHAR_LEN_BITS must be also set to 6, 5, 4 or 3 respectively.
// Default is 64.
// If SPI_MAX_CHAR is 64, SPI_MAX_CHAR_64 must be defined, otherwise comment it
// 128, 64, 32, 16 and 8. SPI_CHAR_LEN_BITS must be also set to 7, 6, 5, 4 or 3 respectively.
// Default is 128.
// If SPI_MAX_CHAR is 64 or 128, SPI_MAX_CHAR_64 or SPI_MAX_CHAR_128 must be defined,
// otherwise comment it out.
//
`define SPI_MAX_CHAR_64 1
`define SPI_MAX_CHAR 64
`define SPI_CHAR_LEN_BITS 6
`define SPI_MAX_CHAR_128 1
//`define SPI_MAX_CHAR_64 1
`define SPI_MAX_CHAR 128
`define SPI_CHAR_LEN_BITS 7
 
//
// Number of device select signals.
67,26 → 69,30
//
// Register offset
//
`define SPI_RX_L 0
`define SPI_RX_H 1
`define SPI_TX_L 0
`define SPI_TX_H 1
`define SPI_CTRL 2
`define SPI_DEVIDE 3
`define SPI_SS 4
`define SPI_RX_0 0
`define SPI_RX_1 1
`define SPI_RX_2 2
`define SPI_RX_3 3
`define SPI_TX_0 0
`define SPI_TX_1 1
`define SPI_TX_2 2
`define SPI_TX_3 3
`define SPI_CTRL 4
`define SPI_DEVIDE 5
`define SPI_SS 6
 
//
// Number of bits in ctrl register
//
`define SPI_CTRL_BIT_NB 12
`define SPI_CTRL_BIT_NB 13
 
//
// Control register bit position
//
`define SPI_CTRL_ASS 11
`define SPI_CTRL_IE 10
`define SPI_CTRL_LSB 9
`define SPI_CTRL_CHAR_LEN 8:3
`define SPI_CTRL_ASS 12
`define SPI_CTRL_IE 11
`define SPI_CTRL_LSB 10
`define SPI_CTRL_CHAR_LEN 9:3
`define SPI_CTRL_TX_NEGEDGE 2
`define SPI_CTRL_RX_NEGEDGE 1
`define SPI_CTRL_GO 0
/trunk/rtl/verilog/spi_shift.v
41,7 → 41,7
`include "spi_defines.v"
`include "timescale.v"
 
module spi_shift (clk, rst, latch_h, latch_l, len, lsb, go,
module spi_shift (clk, rst, latch, len, lsb, go,
pos_edge, neg_edge, rx_negedge, tx_negedge,
tip, last,
p_in, p_out, s_clk, s_in, s_out);
50,8 → 50,7
input clk; // system clock
input rst; // reset
input latch_h; // latch_h signal for storing the data in shift register
input latch_l; // latch_l signal for storing the data in shift register
input [3:0] latch; // latch signal for storing the data in shift register
input [`SPI_CHAR_LEN_BITS-1:0] len; // data len in bits (minus one)
input lsb; // lbs first on the line
input go; // start stansfer
127,15 → 126,26
begin
if (rst)
data <= #Tp {`SPI_MAX_CHAR{1'b0}};
`ifdef SPI_MAX_CHAR_128
else if (latch[0] && !tip)
data[31:0] <= #Tp p_in[31:0];
else if (latch[1] && !tip)
data[63:32] <= #Tp p_in[31:0];
else if (latch[2] && !tip)
data[95:64] <= #Tp p_in[31:0];
else if (latch[3] && !tip)
data[127:96] <= #Tp p_in[31:0];
`else
`ifdef SPI_MAX_CHAR_64
else if (latch_l && !tip)
else if (latch[0] && !tip)
data[31:0] <= #Tp p_in[31:0];
else if (latch_h && !tip)
else if (latch[1] && !tip)
data[63:32] <= #Tp p_in[31:0];
`else
else if (latch_l && !tip)
else if (latch[0] && !tip)
data <= #Tp p_in[`SPI_MAX_CHAR-1:0];
`endif
`endif
else
data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]] <= #Tp rx_clk ? s_in : data[rx_bit_pos[`SPI_CHAR_LEN_BITS-1:0]];
end
/trunk/doc/spi.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
/trunk/doc/src/spi.doc Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream

powered by: WebSVN 2.1.0

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