|  | @@ -20,65 +20,82 @@ module spirom (
 | 
	
		
			
				|  |  |  	       output reg	 spi_cs_n,
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	       /* SDRAM interface */
 | 
	
		
			
				|  |  | -	       output [15:0]	 wd, // Data to RAM
 | 
	
		
			
				|  |  | +	       output [15:0]	 wd,    // Data to RAM
 | 
	
		
			
				|  |  |  	       (* syn_preserve = 1 *)	// Don't merge into FIFO
 | 
	
		
			
				|  |  |  	       output [24:1]	 waddr, // RAM address
 | 
	
		
			
				|  |  | -	       output reg [1:0]  wrq, // Write request (min 4/8 bytes)
 | 
	
		
			
				|  |  | -	       input		 wacc, // Data accepted (ready for next data)
 | 
	
		
			
				|  |  | +	       output reg [1:0]  wrq,   // Write request (min 4/8 bytes)
 | 
	
		
			
				|  |  | +	       input		 wacc,  // Data accepted (ready for next data)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	       /* CPU control interface */
 | 
	
		
			
				|  |  |  	       output reg [31:0] cpu_rdata,
 | 
	
		
			
				|  |  |  	       input [31:0]	 cpu_wdata,
 | 
	
		
			
				|  |  |  	       input		 cpu_valid,
 | 
	
		
			
				|  |  |  	       input [3:0]	 cpu_wstrb,
 | 
	
		
			
				|  |  | -	       input [1:0]	 cpu_addr,
 | 
	
		
			
				|  |  | +	       input [2:0]	 cpu_addr,
 | 
	
		
			
				|  |  |  	       output reg	 irq
 | 
	
		
			
				|  |  |  	       );
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -   reg [24:3] ramstart;
 | 
	
		
			
				|  |  | -   reg [23:3] romstart;
 | 
	
		
			
				|  |  | -   reg [23:3] datalen;
 | 
	
		
			
				|  |  | -   reg	      is_spi;
 | 
	
		
			
				|  |  | +   reg [24:2] ramstart;
 | 
	
		
			
				|  |  | +   reg [31:0] romcmd;
 | 
	
		
			
				|  |  | +   reg [23:2] datalen;
 | 
	
		
			
				|  |  | +   reg [2:0]  cmdlen;
 | 
	
		
			
				|  |  |     reg	      go_zero;
 | 
	
		
			
				|  |  |     reg	      go_spi;
 | 
	
		
			
				|  |  | -   reg	      done;
 | 
	
		
			
				|  |  | +   reg	      spi_dual;
 | 
	
		
			
				|  |  | +   reg	      spi_more;		// Do not raise CS# after command done
 | 
	
		
			
				|  |  | +   reg	      ram_done;
 | 
	
		
			
				|  |  | +   reg	      ram_done_q;
 | 
	
		
			
				|  |  |     reg [1:0]  done_q;
 | 
	
		
			
				|  |  | +   reg	      busy;
 | 
	
		
			
				|  |  | +   reg [31:0] spi_in_shr;	// Input shift register for one-bit input
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +   reg        spi_active;
 | 
	
		
			
				|  |  | +   reg	      spi_active_q;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     always @(negedge rst_n or posedge sys_clk)
 | 
	
		
			
				|  |  |       if (~rst_n)
 | 
	
		
			
				|  |  |         begin
 | 
	
		
			
				|  |  | -	  ramstart <= 23'bx;
 | 
	
		
			
				|  |  | -	  romstart <= 23'bx;
 | 
	
		
			
				|  |  | -	  datalen  <= 21'bx;
 | 
	
		
			
				|  |  | -	  is_spi   <= 1'b0;
 | 
	
		
			
				|  |  | -	  go_zero  <= 1'b0;
 | 
	
		
			
				|  |  | -	  go_spi   <= 1'b0;
 | 
	
		
			
				|  |  | -	  done_q   <= 2'b11;
 | 
	
		
			
				|  |  | -	  irq      <= 1'b1;
 | 
	
		
			
				|  |  | +	  ramstart     <= 23'b0;
 | 
	
		
			
				|  |  | +	  romcmd       <= 32'b0;
 | 
	
		
			
				|  |  | +	  datalen      <= 22'b0;
 | 
	
		
			
				|  |  | +	  cmdlen       <= 3'bx;
 | 
	
		
			
				|  |  | +	  go_zero      <= 1'b0;
 | 
	
		
			
				|  |  | +	  go_spi       <= 1'b0;
 | 
	
		
			
				|  |  | +	  ram_done_q   <= 1'b1;
 | 
	
		
			
				|  |  | +	  done_q       <= 2'b11;
 | 
	
		
			
				|  |  | +	  busy         <= 1'b0;
 | 
	
		
			
				|  |  | +	  spi_active_q <= 1'b0;
 | 
	
		
			
				|  |  | +	  irq          <= 1'b1;
 | 
	
		
			
				|  |  | +	  spi_dual     <= 1'b0;
 | 
	
		
			
				|  |  | +	  spi_more     <= 1'b0;
 | 
	
		
			
				|  |  |         end
 | 
	
		
			
				|  |  |       else
 | 
	
		
			
				|  |  |         begin
 | 
	
		
			
				|  |  | -	  done_q <= { done_q[0], done };
 | 
	
		
			
				|  |  | +	  ram_done_q   <= ram_done;
 | 
	
		
			
				|  |  | +	  spi_active_q <= spi_active;
 | 
	
		
			
				|  |  | +	  done_q   <= { done_q[0], ram_done_q & ~spi_active_q };
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	  irq <= ~(busy | spi_active_q);
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	  if (cpu_valid & cpu_wstrb[0])
 | 
	
		
			
				|  |  |  	    begin
 | 
	
		
			
				|  |  | -	       // Only full word writes supported!!
 | 
	
		
			
				|  |  | +	       // Only full word accesses supported via DMA!!
 | 
	
		
			
				|  |  |  	       case (cpu_addr)
 | 
	
		
			
				|  |  |  		 2'b00: begin
 | 
	
		
			
				|  |  | -		    ramstart <= cpu_wdata[24:3];
 | 
	
		
			
				|  |  | +		    ramstart <= cpu_wdata[24:2];
 | 
	
		
			
				|  |  |  		 end
 | 
	
		
			
				|  |  |  		 2'b01: begin
 | 
	
		
			
				|  |  | -		    romstart <= cpu_wdata[23:3];
 | 
	
		
			
				|  |  | -		    is_spi <= |cpu_wdata[23:3];
 | 
	
		
			
				|  |  | +		    romcmd   <= cpu_wdata[31:0];
 | 
	
		
			
				|  |  |  		 end
 | 
	
		
			
				|  |  |  		 2'b10: begin
 | 
	
		
			
				|  |  | -		    datalen <= cpu_wdata[23:3];
 | 
	
		
			
				|  |  | -		    if (|cpu_wdata[23:3])
 | 
	
		
			
				|  |  | -		      begin
 | 
	
		
			
				|  |  | -			 go_zero <= ~is_spi;
 | 
	
		
			
				|  |  | -			 go_spi  <=  is_spi;
 | 
	
		
			
				|  |  | -			 irq     <=  1'b0;
 | 
	
		
			
				|  |  | -		      end
 | 
	
		
			
				|  |  | +		    datalen  <= cpu_wdata[23:2];
 | 
	
		
			
				|  |  | +		    cmdlen   <= cpu_wdata[26:24];
 | 
	
		
			
				|  |  | +		    go_spi   <= cpu_wdata[26:24] != 3'd0;
 | 
	
		
			
				|  |  | +		    go_zero  <= cpu_wdata[26:24] == 3'd0;
 | 
	
		
			
				|  |  | +		    spi_dual <= cpu_wdata[27];
 | 
	
		
			
				|  |  | +		    spi_more <= cpu_wdata[28];
 | 
	
		
			
				|  |  | +		    busy     <= 1'b1;
 | 
	
		
			
				|  |  | +		    irq      <= 1'b0;
 | 
	
		
			
				|  |  |  		 end
 | 
	
		
			
				|  |  |  		 default: begin
 | 
	
		
			
				|  |  |  		    // Do nothing
 | 
	
	
		
			
				|  | @@ -89,16 +106,18 @@ module spirom (
 | 
	
		
			
				|  |  |  	    begin
 | 
	
		
			
				|  |  |  	       go_zero <= 1'b0;
 | 
	
		
			
				|  |  |  	       go_spi  <= 1'b0;
 | 
	
		
			
				|  |  | -	       irq     <= 1'b1;
 | 
	
		
			
				|  |  | +	       busy    <= 1'b0;
 | 
	
		
			
				|  |  |  	    end
 | 
	
		
			
				|  |  |         end // else: !if(~rst_n)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     always_comb
 | 
	
		
			
				|  |  |       case (cpu_addr)
 | 
	
		
			
				|  |  | -       2'b00: cpu_rdata = { 7'b0, ramstart, 3'b0 };
 | 
	
		
			
				|  |  | -       2'b01: cpu_rdata = { 8'b0, romstart, 3'b0 };
 | 
	
		
			
				|  |  | -       2'b10: cpu_rdata = { 8'b0, datalen,  3'b0 };
 | 
	
		
			
				|  |  | -       2'b11: cpu_rdata = { 31'b0, irq };
 | 
	
		
			
				|  |  | +       3'b000: cpu_rdata = { 7'b0, ramstart, 2'b0 };
 | 
	
		
			
				|  |  | +       3'b001: cpu_rdata = romcmd;
 | 
	
		
			
				|  |  | +       3'b010: cpu_rdata = { 3'b0, spi_more, spi_dual, cmdlen, datalen,  2'b0 };
 | 
	
		
			
				|  |  | +       3'b011: cpu_rdata = { 31'b0, irq };
 | 
	
		
			
				|  |  | +       3'b100: cpu_rdata = spi_in_shr;
 | 
	
		
			
				|  |  | +       default: cpu_rdata = 32'bx;
 | 
	
		
			
				|  |  |       endcase // case (cpu_addr)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     //
 | 
	
	
		
			
				|  | @@ -110,6 +129,7 @@ module spirom (
 | 
	
		
			
				|  |  |     wire [11:0]		  wrusedw;
 | 
	
		
			
				|  |  |     wire [8:0]		  rdusedw;
 | 
	
		
			
				|  |  |     wire [15:0]		  fifo_out;
 | 
	
		
			
				|  |  | +   reg			  from_spi;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     ddufifo spirom_fifo (
 | 
	
		
			
				|  |  |  			.aclr ( ~rst_n ),
 | 
	
	
		
			
				|  | @@ -121,7 +141,7 @@ module spirom (
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  			.rdclk ( ram_clk ),
 | 
	
		
			
				|  |  |  			.q ( fifo_out ),
 | 
	
		
			
				|  |  | -			.rdreq ( wacc & go_spi ),
 | 
	
		
			
				|  |  | +			.rdreq ( wacc & from_spi ),
 | 
	
		
			
				|  |  |  			.rdusedw ( rdusedw )
 | 
	
		
			
				|  |  |  			);
 | 
	
		
			
				|  |  |  
 | 
	
	
		
			
				|  | @@ -131,15 +151,15 @@ module spirom (
 | 
	
		
			
				|  |  |     // Shuffle fifo_out because SPI brings in data in bigendian bit
 | 
	
		
			
				|  |  |     // order within bytes, but the FIFO IP assumes littleendian
 | 
	
		
			
				|  |  |     //
 | 
	
		
			
				|  |  | -   assign wd[ 7: 6] = {2{go_spi}} & fifo_out[ 1: 0];
 | 
	
		
			
				|  |  | -   assign wd[ 5: 4] = {2{go_spi}} & fifo_out[ 3: 2];
 | 
	
		
			
				|  |  | -   assign wd[ 3: 2] = {2{go_spi}} & fifo_out[ 5: 4];
 | 
	
		
			
				|  |  | -   assign wd[ 1: 0] = {2{go_spi}} & fifo_out[ 7: 6];
 | 
	
		
			
				|  |  | +   assign wd[ 7: 6] = {2{from_spi}} & fifo_out[ 1: 0];
 | 
	
		
			
				|  |  | +   assign wd[ 5: 4] = {2{from_spi}} & fifo_out[ 3: 2];
 | 
	
		
			
				|  |  | +   assign wd[ 3: 2] = {2{from_spi}} & fifo_out[ 5: 4];
 | 
	
		
			
				|  |  | +   assign wd[ 1: 0] = {2{from_spi}} & fifo_out[ 7: 6];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -   assign wd[15:14] = {2{go_spi}} & fifo_out[ 9: 8];
 | 
	
		
			
				|  |  | -   assign wd[13:12] = {2{go_spi}} & fifo_out[11:10];
 | 
	
		
			
				|  |  | -   assign wd[11:10] = {2{go_spi}} & fifo_out[13:12];
 | 
	
		
			
				|  |  | -   assign wd[ 9: 8] = {2{go_spi}} & fifo_out[15:14];
 | 
	
		
			
				|  |  | +   assign wd[15:14] = {2{from_spi}} & fifo_out[ 9: 8];
 | 
	
		
			
				|  |  | +   assign wd[13:12] = {2{from_spi}} & fifo_out[11:10];
 | 
	
		
			
				|  |  | +   assign wd[11:10] = {2{from_spi}} & fifo_out[13:12];
 | 
	
		
			
				|  |  | +   assign wd[ 9: 8] = {2{from_spi}} & fifo_out[15:14];
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     reg [24:1] waddr_q;
 | 
	
		
			
				|  |  |     reg [23:1] ram_data_ctr;
 | 
	
	
		
			
				|  | @@ -154,7 +174,7 @@ module spirom (
 | 
	
		
			
				|  |  |  	  waddr_q      <= 24'bx;
 | 
	
		
			
				|  |  |  	  ram_data_ctr <= 23'bx;
 | 
	
		
			
				|  |  |  	  wacc_q       <= 1'b0;
 | 
	
		
			
				|  |  | -	  done	       <= 1'b1;
 | 
	
		
			
				|  |  | +	  ram_done     <= 1'b1;
 | 
	
		
			
				|  |  |  	  go_ram_q     <= 2'b00;
 | 
	
		
			
				|  |  |  	  wrq          <= 2'b00;
 | 
	
		
			
				|  |  |         end
 | 
	
	
		
			
				|  | @@ -162,13 +182,19 @@ module spirom (
 | 
	
		
			
				|  |  |         begin
 | 
	
		
			
				|  |  |  	  wrq <= 2'b00;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	  if (go_spi & ~done)
 | 
	
		
			
				|  |  | +	  if (ram_done)
 | 
	
		
			
				|  |  | +	    begin
 | 
	
		
			
				|  |  | +	       wrq <= 2'b00;
 | 
	
		
			
				|  |  | +	    end
 | 
	
		
			
				|  |  | +	  else if (from_spi)
 | 
	
		
			
				|  |  |  	    begin
 | 
	
		
			
				|  |  | +	       // Reading from SPI ROM
 | 
	
		
			
				|  |  |  	       wrq[0] <= rdusedw >=  9'd4; // 4*2 =  8 bytes min available
 | 
	
		
			
				|  |  |  	       wrq[1] <= rdusedw >=  9'd8; // 8*2 = 16 bytes min available
 | 
	
		
			
				|  |  |  	    end
 | 
	
		
			
				|  |  | -	  else if (go_zero & ~done)
 | 
	
		
			
				|  |  | +	  else
 | 
	
		
			
				|  |  |  	    begin
 | 
	
		
			
				|  |  | +	       // Zeroing memory
 | 
	
		
			
				|  |  |  	       wrq[0] <= |ram_data_ctr[23:3];
 | 
	
		
			
				|  |  |  	       wrq[1] <= |ram_data_ctr[23:4];
 | 
	
		
			
				|  |  |  	    end
 | 
	
	
		
			
				|  | @@ -178,24 +204,27 @@ module spirom (
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	  if (go_ram_q == 2'b01)
 | 
	
		
			
				|  |  |  	    begin
 | 
	
		
			
				|  |  | -	       waddr_q      <= {ramstart, 2'b00};
 | 
	
		
			
				|  |  | -	       ram_data_ctr <= { datalen, 2'b00};
 | 
	
		
			
				|  |  | -	       done         <= 1'b0;
 | 
	
		
			
				|  |  | +	       waddr_q      <= { ramstart, 1'b0 };
 | 
	
		
			
				|  |  | +	       ram_data_ctr <= { datalen,  1'b0 };
 | 
	
		
			
				|  |  | +	       ram_done     <= !datalen;
 | 
	
		
			
				|  |  | +	       from_spi     <= go_spi;
 | 
	
		
			
				|  |  |  	    end
 | 
	
		
			
				|  |  | -	  else if (~done)
 | 
	
		
			
				|  |  | +	  else if (~ram_done)
 | 
	
		
			
				|  |  |  	    begin
 | 
	
		
			
				|  |  |  	       waddr_q      <= waddr_q + wacc_q;
 | 
	
		
			
				|  |  |  	       ram_data_ctr <= ram_data_ctr - wacc_q;
 | 
	
		
			
				|  |  | -	       done         <= !(ram_data_ctr - wacc_q);
 | 
	
		
			
				|  |  | +	       ram_done     <= !(ram_data_ctr - wacc_q);
 | 
	
		
			
				|  |  |  	    end
 | 
	
		
			
				|  |  |         end // else: !if(~rst_n)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -   reg [5:0]   spi_cmd_ctr;
 | 
	
		
			
				|  |  | +   // Negative indicies refer to fractional bytes
 | 
	
		
			
				|  |  | +   reg [2:-3]  spi_cmd_ctr;
 | 
	
		
			
				|  |  |     reg [23:-2] spi_data_ctr;
 | 
	
		
			
				|  |  |     reg	       spi_clk_en = 1'b0;
 | 
	
		
			
				|  |  |     reg	       spi_mosi_en;
 | 
	
		
			
				|  |  |     reg [1:0]   go_spi_q;
 | 
	
		
			
				|  |  |     wire        go_spi_s;
 | 
	
		
			
				|  |  | +   reg	       spi_more_q;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     // Explicit synchronizer for go_spi
 | 
	
		
			
				|  |  |     synchronizer #(.width(1)) go_spi_synchro
 | 
	
	
		
			
				|  | @@ -216,7 +245,11 @@ module spirom (
 | 
	
		
			
				|  |  |  	  spi_in_req   <= 1'b0;
 | 
	
		
			
				|  |  |  	  spi_in_req_q <= 1'b0;
 | 
	
		
			
				|  |  |  	  spi_mosi_en  <= 1'b1;
 | 
	
		
			
				|  |  | -	  go_spi_q     <= 4'b0000;
 | 
	
		
			
				|  |  | +	  spi_in_q     <= 2'bx;
 | 
	
		
			
				|  |  | +	  spi_in_shr   <= 32'b0;
 | 
	
		
			
				|  |  | +	  go_spi_q     <= 2'b00;
 | 
	
		
			
				|  |  | +	  spi_active   <= 1'b0;
 | 
	
		
			
				|  |  | +	  spi_more_q   <= 1'b0;
 | 
	
		
			
				|  |  |         end
 | 
	
		
			
				|  |  |       else
 | 
	
		
			
				|  |  |         begin
 | 
	
	
		
			
				|  | @@ -225,41 +258,49 @@ module spirom (
 | 
	
		
			
				|  |  |  	  spi_in_req   <= 1'b0;
 | 
	
		
			
				|  |  |  	  spi_in_req_q <= spi_in_req;
 | 
	
		
			
				|  |  |  	  spi_clk_en   <= 1'b0;
 | 
	
		
			
				|  |  | -	  spi_cs_n     <= 1'b1;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	  // Note: datalen <- spi_data_ctr is a 2-cycle multipath
 | 
	
		
			
				|  |  |  	  if (go_spi_q == 2'b01)
 | 
	
		
			
				|  |  |  	    begin
 | 
	
		
			
				|  |  | -	       spi_data_ctr <= { datalen, 5'b0 };
 | 
	
		
			
				|  |  | -	       spi_cmd_ctr  <= 6'b0;
 | 
	
		
			
				|  |  | +	       spi_cmd_ctr  <= { cmdlen,  3'b0 };
 | 
	
		
			
				|  |  | +	       spi_data_ctr <= { datalen, 4'b0 };
 | 
	
		
			
				|  |  | +	       spi_active   <= 1'b1;
 | 
	
		
			
				|  |  |  	       spi_cs_n     <= 1'b0;
 | 
	
		
			
				|  |  | +	       spi_more_q   <= spi_more;
 | 
	
		
			
				|  |  |  	    end
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	  if ( ~|spi_data_ctr | ~go_spi_q[1] )
 | 
	
		
			
				|  |  | +	  if ( ~|{spi_data_ctr, spi_cmd_ctr} )
 | 
	
		
			
				|  |  |  	    begin
 | 
	
		
			
				|  |  |  	       spi_clk_en  <= 1'b0;
 | 
	
		
			
				|  |  |  	       spi_mosi_en <= 1'b1;
 | 
	
		
			
				|  |  | +	       spi_active  <= 1'b0;
 | 
	
		
			
				|  |  | +	       spi_cs_n    <= ~spi_more_q;
 | 
	
		
			
				|  |  |  	    end
 | 
	
		
			
				|  |  |  	  else
 | 
	
		
			
				|  |  |  	    begin
 | 
	
		
			
				|  |  | -	       spi_cs_n   <= 1'b0;
 | 
	
		
			
				|  |  | -	       if ( ~spi_cs_n )
 | 
	
		
			
				|  |  | +	       spi_active   <= 1'b1;
 | 
	
		
			
				|  |  | +	       spi_cs_n     <= 1'b0;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	       if ( spi_active )
 | 
	
		
			
				|  |  |  		 begin
 | 
	
		
			
				|  |  |  		    // 64/4 = 16 bytes min space
 | 
	
		
			
				|  |  |  		    spi_clk_en <= (~wrusedw) >= 12'd128;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  |  		    if ( spi_clk_en )
 | 
	
		
			
				|  |  |  		      begin
 | 
	
		
			
				|  |  | -			 if ( spi_cmd_ctr[5] & spi_cmd_ctr[2] )
 | 
	
		
			
				|  |  | -			   spi_mosi_en <= 1'b0;
 | 
	
		
			
				|  |  | +			 spi_in_shr   <= { spi_in_shr[30:0], spi_io[1] };
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -			 if ( spi_cmd_ctr[5] & spi_cmd_ctr[3] )
 | 
	
		
			
				|  |  | +			 if ( spi_cmd_ctr == 6'd1 )
 | 
	
		
			
				|  |  | +			      spi_mosi_en  <= ~spi_dual;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +			 if ( spi_cmd_ctr == 6'd0 )
 | 
	
		
			
				|  |  |  			   begin
 | 
	
		
			
				|  |  | -			      spi_in_req <= 1'b1;
 | 
	
		
			
				|  |  | +			      spi_in_req   <= 1'b1;
 | 
	
		
			
				|  |  |  			      spi_data_ctr <= spi_data_ctr - 1'b1;
 | 
	
		
			
				|  |  |  			   end
 | 
	
		
			
				|  |  |  			 else
 | 
	
		
			
				|  |  |  			   begin
 | 
	
		
			
				|  |  | -			      spi_cmd_ctr <= spi_cmd_ctr + 1'b1;
 | 
	
		
			
				|  |  | +			      spi_cmd_ctr <= spi_cmd_ctr - 1'b1;
 | 
	
		
			
				|  |  |  			   end
 | 
	
		
			
				|  |  |  		      end // if ( spi_clk_en )
 | 
	
		
			
				|  |  |  		 end // if ( ~spi_cs_n )
 | 
	
	
		
			
				|  | @@ -267,29 +308,26 @@ module spirom (
 | 
	
		
			
				|  |  |         end // else: !if(~rst_n)
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     // SPI output data is shifted on the negative edge
 | 
	
		
			
				|  |  | -   reg [31:0] spi_cmd;
 | 
	
		
			
				|  |  | +   reg [31:0] spi_out_shr;
 | 
	
		
			
				|  |  |     reg	      spi_clk_en_q;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -   assign spi_io[0] = spi_mosi_en ? spi_cmd[31] : 1'bz;
 | 
	
		
			
				|  |  | +   assign spi_io[0] = spi_mosi_en ? spi_out_shr[31] : 1'bz;
 | 
	
		
			
				|  |  |     assign spi_io[1] = 1'bz;
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     always @(negedge rst_n or negedge rom_clk)
 | 
	
		
			
				|  |  |       if (~rst_n)
 | 
	
		
			
				|  |  |         begin
 | 
	
		
			
				|  |  | -	  spi_cmd      <= 32'bx;	// Fast Read Dual Output
 | 
	
		
			
				|  |  | +	  spi_out_shr  <= 32'b0;
 | 
	
		
			
				|  |  |  	  spi_clk_en_q <= 1'b0;
 | 
	
		
			
				|  |  |         end
 | 
	
		
			
				|  |  |       else
 | 
	
		
			
				|  |  |         begin
 | 
	
		
			
				|  |  | -	  if (spi_cs_n)
 | 
	
		
			
				|  |  | -	    begin
 | 
	
		
			
				|  |  | -	       spi_cmd[31:24] <= 8'h3b;	// Fast Read Dual Output
 | 
	
		
			
				|  |  | -	       spi_cmd[23: 0] <= { romstart, 3'b000 }; // Byte address
 | 
	
		
			
				|  |  | -	    end
 | 
	
		
			
				|  |  | -
 | 
	
		
			
				|  |  |  	  spi_clk_en_q <= spi_clk_en;
 | 
	
		
			
				|  |  | -	  if ( spi_clk_en_q )
 | 
	
		
			
				|  |  | -	    spi_cmd <= (spi_cmd << 1) | 1'b1;
 | 
	
		
			
				|  |  | +
 | 
	
		
			
				|  |  | +	  if (~spi_active)
 | 
	
		
			
				|  |  | +	    spi_out_shr <= romcmd;
 | 
	
		
			
				|  |  | +	  else if ( spi_clk_en_q )
 | 
	
		
			
				|  |  | +	    spi_out_shr <= { spi_out_shr[30:0], 1'b0 };
 | 
	
		
			
				|  |  |         end
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |     //
 |