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