-
Notifications
You must be signed in to change notification settings - Fork 1
/
spi_tb.v
107 lines (86 loc) · 2.33 KB
/
spi_tb.v
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
module spi_tb(input clk, input rst, input cs, input rd, input wr,
input [7:0] din, output [7:0] dout, output miso, output mosi,
output sclk, output done, output [7:0] prev_input, output [7:0] prev_output);
defparam dut.DWIDTH = 8;
wire [7:0] din;
wire [7:0] dout;
wire miso;
wire mosi;
wire sclk;
wire done;
reg [7:0] prev_input;
reg [7:0] prev_output;
wire [7:0] shreg_data;
spi_core dut (
.clk(clk),
.rst(rst),
.cs(cs),
.rd(rd),
.wr(wr),
.din(din),
.dout(dout),
.miso(miso),
.mosi(mosi),
.sclk(sclk),
.done(done)
);
spi_shreg #(8) spi_sec(
.sclk(sclk),
.cs(1'b0),
.mosi(mosi),
.miso(miso),
.data(shreg_data)
);
// When an xfer starts, save the previous input/output for
// comparison purposes.
always @(posedge clk) begin
if (~rd & wr & cs) begin
prev_input <= din;
prev_output <= shreg_data;
end
end
`ifdef FORMAL
// Assume well-behaved upstream- whatever's connected to the SPI
// core has properly-functioning control signals.
assume property (!((rd == 1) && (wr == 1)));
assume property (!((cs == 1) && (wr == 1) && (done == 0)));
initial assume (wr == 1);
initial assume (cs == 1);
initial assume (done == 1);
initial assume (prev_input == shreg_data);
initial assume (prev_output == dout);
// Goal: If no xfer is taking place, the SPI primary's reg
// should equal the secondary's reg _just_ before the xfer started.
// The secondary's reg should equal the input data bus _just_
// before the xfer started.
always @* begin
if (done) begin
assert(prev_input == shreg_data);
assert(prev_output == dout);
assume(sclk == 0);
end
end
reg last_clk = 0;
always @($global_clock) begin
last_clk <= clk;
assume(last_clk != clk);
end
`endif
endmodule
module spi_shreg(input sclk, input cs, input mosi, output reg miso,
output [DWIDTH - 1:0] data);
parameter DWIDTH = 8;
reg tmp_bit;
reg [DWIDTH - 1:0] data;
assign miso = data[DWIDTH - 1];
always @(posedge sclk) begin
if (~cs) begin
tmp_bit <= mosi;
end
end
always @(negedge sclk) begin
if (~cs) begin
data[DWIDTH - 1:0] <= { data[DWIDTH - 2:0], tmp_bit };
end
end
endmodule