So, although 65SPI is available as ABEL, the project on the web site won't load into ISE 14, and I thought I'd try my hand at re-implementing it as Verilog. (Yep, tried an ABEL -> verilog converter, and the results were horrid).
I figured it'd be something I could check operation by running it alongside the original jed file, and I'd get Verilog practice.
Most of it I have figured out, but I think my incomplete understanding of Verilog is tripping me up, and the tutorials don't seem to make sense in this area.
My first issue is registers in secondary modules. I have this:
Code:
module t_register(clock, reset, enable, d, q, trigger);
parameter WIDTH = 8 ;
parameter RESET = 0 ;
input clock;
input reset;
input enable;
inout [WIDTH-1:0] d;
output [WIDTH-1:0] q;
output trigger;
reg [WIDTH-1:0] q;
reg trigger;
always @ (negedge clock, posedge reset)
begin
if(reset)
q <= RESET;
else if(enable)
begin
q <= d;
trigger <= 1;
end
end
endmodule
Looks and works fine. But, if in the top-level module I do:
t_register #(.WIDTH(8)) spi_data_reg(clock, reset_in, spi_data_reg_ce, data, spi_data, BUSY);
always (...)
BUSY <= 0; //. we are done with the 8 bit transfer...
I get an error that it's an illegal lvalue. Duh, the t_register needs trigger output defined as reg, incoming var needs to be wire, but I need to deal with it in two places. I worked around the issue by doing:
wire jim;
reg BUSY;
t_register #(.WIDTH(8)) spi_data_reg(clock, reset_in, spi_data_reg_ce, data, spi_data, jim);
always (posedge jim)
BUSY <= 1;
always (...)
BUSY <= 0; //. we are done with the 8 bit transfer...
but that seems wrong, and a waste of a flop (assuming the code does not optimize it away). I figure this is an easy "Jim does not understand Verilog" thing, but I can't seem to find the relevant tutorial. I might be able to remove the issue by pulling the module definition into the top level part of my file, but that can't be a good plan long term (and, not sure it will work anyway).
The second issue is needing to change a var from two different always blocks:
Code:
always @ (posedge sck)
if(BUSY)
begin
if((CPHA & !CPOL) | (!CPHA & CPOL))
if(bits == 8)
begin
spi_data_in <= shift_reg;
BUSY <= 0;
TXC <= 1;
end
else
begin
shift_reg <= {shift_reg[6:0], miso_reg};
bits <= bits + 1;
end
if((!CPHA & !CPOL) | (CPHA & CPOL))
begin
miso_reg <= miso;
end
end
always @ (negedge sck)
if(BUSY)
begin
if((!CPHA & !CPOL) | (CPHA & CPOL))
if(bits == 8)
begin
spi_data_in <= shift_reg;
BUSY <= 0;
TXC <= 1;
end
else
begin
shift_reg <= {shift_reg[6:0], miso_reg};
bits <= bits + 1;
end
if((CPHA & !CPOL) | (!CPHA & CPOL))
begin
miso_reg <= miso;
end
end
miso_reg gets a complaint, as does the shift register. I think I can understand why (the synthesis tool wants the flops to be rising or falling clock, but not both). I assume I need to run everything against the master clock and then just put a bunch of if statements in the always blocks, but I thought I would check before I start adding in all the extra combinatorial logic... (I think I could create a schematic version of this that would not need all the combinatorial logic, so I thought it might be possible...)
Jim
Jim