Add spimemio QSPI support
This commit is contained in:
		
							parent
							
								
									89ad9fc85a
								
							
						
					
					
						commit
						53b175d0fb
					
				|  | @ -66,6 +66,11 @@ module spimemio ( | |||
| 	assign ready = valid && (addr == rd_addr) && rd_valid; | ||||
| 	wire jump = valid && !ready && (addr != rd_addr+4) && rd_valid; | ||||
| 
 | ||||
| 	reg config_ddr = 0; | ||||
| 	reg config_qspi = 0; | ||||
| 	reg config_cont = 0; | ||||
| 	reg [3:0] config_dummy = 1; | ||||
| 
 | ||||
| 	spimemio_xfer xfer ( | ||||
| 		.clk          (clk         ), | ||||
| 		.resetn       (xfer_resetn ), | ||||
|  | @ -99,7 +104,6 @@ module spimemio ( | |||
| 	always @(posedge clk) begin | ||||
| 		xfer_resetn <= 1; | ||||
| 		din_valid <= 0; | ||||
| 		din_data <= 8'h 00; | ||||
| 
 | ||||
| 		if (!resetn) begin | ||||
| 			state <= 0; | ||||
|  | @ -133,9 +137,11 @@ module spimemio ( | |||
| 				0: begin | ||||
| 					din_valid <= 1; | ||||
| 					din_data <= 8'h ff; | ||||
| 					if (din_ready) | ||||
| 					if (din_ready) begin | ||||
| 						din_valid <= 0; | ||||
| 						state <= 1; | ||||
| 					end | ||||
| 				end | ||||
| 				1: begin | ||||
| 					if (dout_valid) begin | ||||
| 						xfer_resetn <= 0; | ||||
|  | @ -145,9 +151,11 @@ module spimemio ( | |||
| 				2: begin | ||||
| 					din_valid <= 1; | ||||
| 					din_data <= 8'h ab; | ||||
| 					if (din_ready) | ||||
| 					if (din_ready) begin | ||||
| 						din_valid <= 0; | ||||
| 						state <= 3; | ||||
| 					end | ||||
| 				end | ||||
| 				3: begin | ||||
| 					if (dout_valid) begin | ||||
| 						xfer_resetn <= 0; | ||||
|  | @ -157,43 +165,60 @@ module spimemio ( | |||
| 				4: begin | ||||
| 					rd_inc <= 0; | ||||
| 					din_valid <= 1; | ||||
| 					din_data <= 8'h 03; | ||||
| 					if (din_ready) | ||||
| 					case ({config_ddr, config_qspi}) | ||||
| 						2'b11: din_data <= 8'h ED; | ||||
| 						2'b01: din_data <= 8'h EB; | ||||
| 						2'b00: din_data <= 8'h 03; | ||||
| 					endcase | ||||
| 					if (din_ready) begin | ||||
| 						din_valid <= 0; | ||||
| 						state <= 5; | ||||
| 					end | ||||
| 				end | ||||
| 				5: begin | ||||
| 					if (valid && !ready) begin | ||||
| 						din_valid <= 1; | ||||
| 						din_data <= addr[23:16]; | ||||
| 						if (din_ready) | ||||
| 						din_qspi <= config_qspi; | ||||
| 						din_ddr <= config_ddr; | ||||
| 						if (din_ready) begin | ||||
| 							din_valid <= 0; | ||||
| 							state <= 6; | ||||
| 						end | ||||
| 					end | ||||
| 				end | ||||
| 				6: begin | ||||
| 					din_valid <= 1; | ||||
| 					din_data <= addr[15:8]; | ||||
| 					if (din_ready) | ||||
| 					if (din_ready) begin | ||||
| 						din_valid <= 0; | ||||
| 						state <= 7; | ||||
| 					end | ||||
| 				end | ||||
| 				7: begin | ||||
| 					din_valid <= 1; | ||||
| 					din_data <= addr[7:0]; | ||||
| 					if (din_ready) | ||||
| 						state <= 8; | ||||
| 					if (din_ready) begin | ||||
| 						din_valid <= 0; | ||||
| 						din_data <= 0; | ||||
| 						state <= config_qspi ? 8 : 9; | ||||
| 					end | ||||
| 				end | ||||
| 				8: begin | ||||
| 					din_valid <= 1; | ||||
| 					din_data <= 8'h 00; | ||||
| 					din_data <= config_cont ? 8'h A5 : 8'h FF; | ||||
| 					if (din_ready) begin | ||||
| 						buffer_wen <= 4'b 0001; | ||||
| 						din_rd <= 1; | ||||
| 						din_data <= config_dummy; | ||||
| 						din_valid <= 0; | ||||
| 						state <= 9; | ||||
| 					end | ||||
| 				end | ||||
| 				9: begin | ||||
| 					din_valid <= 1; | ||||
| 					din_data <= 8'h 00; | ||||
| 					if (din_ready) begin | ||||
| 						buffer_wen <= 4'b 0010; | ||||
| 						buffer_wen <= 4'b 0001; | ||||
| 						din_valid <= 0; | ||||
| 						state <= 10; | ||||
| 					end | ||||
| 				end | ||||
|  | @ -201,17 +226,26 @@ module spimemio ( | |||
| 					din_valid <= 1; | ||||
| 					din_data <= 8'h 00; | ||||
| 					if (din_ready) begin | ||||
| 						buffer_wen <= 4'b 0100; | ||||
| 						buffer_wen <= 4'b 0010; | ||||
| 						din_valid <= 0; | ||||
| 						state <= 11; | ||||
| 					end | ||||
| 				end | ||||
| 				11: begin | ||||
| 					din_valid <= 1; | ||||
| 					if (din_ready) begin | ||||
| 						buffer_wen <= 4'b 0100; | ||||
| 						din_valid <= 0; | ||||
| 						state <= 12; | ||||
| 					end | ||||
| 				end | ||||
| 				12: begin | ||||
| 					if (!rd_wait || valid) begin | ||||
| 						din_valid <= 1; | ||||
| 						din_data <= 8'h 00; | ||||
| 						if (din_ready) begin | ||||
| 							buffer_wen <= 4'b 1000; | ||||
| 							state <= 8; | ||||
| 							din_valid <= 0; | ||||
| 							state <= 9; | ||||
| 						end | ||||
| 					end | ||||
| 				end | ||||
|  | @ -222,7 +256,14 @@ module spimemio ( | |||
| 				rd_valid <= 0; | ||||
| 				xfer_resetn <= 0; | ||||
| 				buffer_wen <= 0; | ||||
| 				if (config_cont) begin | ||||
| 					state <= 5; | ||||
| 				end else begin | ||||
| 					state <= 4; | ||||
| 					din_qspi <= 0; | ||||
| 					din_ddr <= 0; | ||||
| 				end | ||||
| 				din_rd <= 0; | ||||
| 			end | ||||
| 		end | ||||
| 	end | ||||
|  | @ -260,13 +301,12 @@ module spimemio_xfer ( | |||
| 	input      flash_io2_di, | ||||
| 	input      flash_io3_di | ||||
| ); | ||||
| 	localparam [3:0] mode_spi = 0; | ||||
| 	reg [3:0] mode; | ||||
| 
 | ||||
| 	reg [7:0] obuffer; | ||||
| 	reg [7:0] ibuffer; | ||||
| 
 | ||||
| 	reg [3:0] count; | ||||
| 	reg [3:0] dummy_count; | ||||
| 
 | ||||
| 	reg xfer_cont; | ||||
| 	reg xfer_qspi; | ||||
| 	reg xfer_ddr; | ||||
|  | @ -276,12 +316,13 @@ module spimemio_xfer ( | |||
| 	reg [7:0] next_ibuffer; | ||||
| 	reg [3:0] next_count; | ||||
| 
 | ||||
| 	reg fetch_next; | ||||
| 	reg last_fetch_next; | ||||
| 	reg fetch; | ||||
| 	reg next_fetch; | ||||
| 	reg last_fetch; | ||||
| 
 | ||||
| 	assign din_ready = din_valid && resetn && fetch_next; | ||||
| 	assign din_ready = din_valid && resetn && next_fetch; | ||||
| 
 | ||||
| 	assign dout_valid = fetch_next && !last_fetch_next; | ||||
| 	assign dout_valid = xfer_ddr ? fetch && !last_fetch : next_fetch && !fetch; | ||||
| 	assign dout_data = ibuffer; | ||||
| 
 | ||||
| 	always @* begin | ||||
|  | @ -298,10 +339,11 @@ module spimemio_xfer ( | |||
| 		next_obuffer = obuffer; | ||||
| 		next_ibuffer = ibuffer; | ||||
| 		next_count = count; | ||||
| 		fetch_next = 0; | ||||
| 		next_fetch = 0; | ||||
| 
 | ||||
| 		case (mode) | ||||
| 			mode_spi: begin | ||||
| 		if (dummy_count == 0) begin | ||||
| 			case ({xfer_ddr, xfer_qspi}) | ||||
| 				2'b 00: begin | ||||
| 					flash_io0_oe = 1; | ||||
| 					flash_io0_do = obuffer[7]; | ||||
| 
 | ||||
|  | @ -312,20 +354,68 @@ module spimemio_xfer ( | |||
| 						next_ibuffer = {ibuffer[6:0], flash_io1_di}; | ||||
| 					end | ||||
| 
 | ||||
| 				fetch_next = (next_count == 0); | ||||
| 					next_fetch = (next_count == 0); | ||||
| 				end | ||||
| 				2'b 01: begin | ||||
| 					flash_io0_oe = !xfer_rd; | ||||
| 					flash_io1_oe = !xfer_rd; | ||||
| 					flash_io2_oe = !xfer_rd; | ||||
| 					flash_io3_oe = !xfer_rd; | ||||
| 
 | ||||
| 					flash_io0_do = obuffer[4]; | ||||
| 					flash_io1_do = obuffer[5]; | ||||
| 					flash_io2_do = obuffer[6]; | ||||
| 					flash_io3_do = obuffer[7]; | ||||
| 
 | ||||
| 					if (flash_clk) begin | ||||
| 						next_obuffer = {obuffer[3:0], 4'b 0000}; | ||||
| 						next_count = count - {|count, 2'b00}; | ||||
| 					end else begin | ||||
| 						next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di}; | ||||
| 					end | ||||
| 
 | ||||
| 					next_fetch = (next_count == 0); | ||||
| 				end | ||||
| 				2'b 11: begin | ||||
| 					flash_io0_oe = !xfer_rd; | ||||
| 					flash_io1_oe = !xfer_rd; | ||||
| 					flash_io2_oe = !xfer_rd; | ||||
| 					flash_io3_oe = !xfer_rd; | ||||
| 
 | ||||
| 					flash_io0_do = obuffer[4]; | ||||
| 					flash_io1_do = obuffer[5]; | ||||
| 					flash_io2_do = obuffer[6]; | ||||
| 					flash_io3_do = obuffer[7]; | ||||
| 
 | ||||
| 					next_obuffer = {obuffer[3:0], 4'b 0000}; | ||||
| 					next_ibuffer = {ibuffer[3:0], flash_io3_di, flash_io2_di, flash_io1_di, flash_io0_di}; | ||||
| 					next_count = count - {|count, 2'b00}; | ||||
| 
 | ||||
| 					next_fetch = (next_count == 0); | ||||
| 				end | ||||
| 			endcase | ||||
| 		end | ||||
| 	end | ||||
| 
 | ||||
| 	always @(posedge clk) begin | ||||
| 		if (!resetn) begin | ||||
| 			mode <= mode_spi; | ||||
| 			last_fetch_next <= 1; | ||||
| 			fetch <= 1; | ||||
| 			last_fetch <= 1; | ||||
| 			flash_csb <= 1; | ||||
| 			flash_clk <= 0; | ||||
| 			count <= 0; | ||||
| 			dummy_count <= 0; | ||||
| 			xfer_cont <= 0; | ||||
| 			xfer_qspi <= 0; | ||||
| 			xfer_ddr <= 0; | ||||
| 			xfer_rd <= 0; | ||||
| 		end else begin | ||||
| 			last_fetch_next <= fetch_next; | ||||
| 			fetch <= next_fetch; | ||||
| 			last_fetch <= xfer_ddr ? fetch : 1; | ||||
| 			if (dummy_count) begin | ||||
| 				flash_clk <= !flash_clk && !flash_csb; | ||||
| 				dummy_count <= dummy_count - flash_clk; | ||||
| 			end else | ||||
| 			if (count) begin | ||||
| 				flash_clk <= !flash_clk && !flash_csb; | ||||
| 				obuffer <= next_obuffer; | ||||
|  | @ -337,8 +427,10 @@ module spimemio_xfer ( | |||
| 				flash_clk <= 0; | ||||
| 
 | ||||
| 				obuffer <= din_data; | ||||
| 				ibuffer <= 8'h 00; | ||||
| 				// ibuffer <= 8'h 00; | ||||
| 
 | ||||
| 				count <= 8; | ||||
| 				dummy_count <= din_rd ? din_data : 0; | ||||
| 
 | ||||
| 				xfer_cont <= din_cont; | ||||
| 				xfer_qspi <= din_qspi; | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue