Update sys.
This commit is contained in:
parent
4cd1724296
commit
89236bc26c
|
@ -13,7 +13,7 @@ set_global_assignment -name PARTITION_NETLIST_TYPE SOURCE -section_id Top
|
|||
set_global_assignment -name PARTITION_FITTER_PRESERVATION_LEVEL PLACEMENT_AND_ROUTING -section_id Top
|
||||
set_global_assignment -name PARTITION_COLOR 16764057 -section_id Top
|
||||
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "17.0.2 Lite Edition"
|
||||
set_global_assignment -name LAST_QUARTUS_VERSION "17.0.2 Standard Edition"
|
||||
|
||||
set_global_assignment -name GENERATE_RBF_FILE ON
|
||||
set_global_assignment -name PROJECT_OUTPUT_DIRECTORY output_files
|
||||
|
|
44
MacPlus.sv
44
MacPlus.sv
|
@ -29,7 +29,7 @@ module emu
|
|||
input RESET,
|
||||
|
||||
//Must be passed to hps_io module
|
||||
inout [45:0] HPS_BUS,
|
||||
inout [48:0] HPS_BUS,
|
||||
|
||||
//Base video clock. Usually equals to CLK_SYS.
|
||||
output CLK_VIDEO,
|
||||
|
@ -39,9 +39,9 @@ module emu
|
|||
output CE_PIXEL,
|
||||
|
||||
//Video aspect ratio for HDMI. Most retro systems have ratio 4:3.
|
||||
//if VIDEO_ARX[12] or VIDEO_ARY[12] is set then [11:0] contains scaled size instead of aspect ratio.
|
||||
output [12:0] VIDEO_ARX,
|
||||
output [12:0] VIDEO_ARY,
|
||||
//if VIDEO_ARX[12] or VIDEO_ARY[12] is set then [11:0] contains scaled size instead of aspect ratio.
|
||||
output [12:0] VIDEO_ARX,
|
||||
output [12:0] VIDEO_ARY,
|
||||
|
||||
output [7:0] VGA_R,
|
||||
output [7:0] VGA_G,
|
||||
|
@ -52,11 +52,12 @@ module emu
|
|||
output VGA_F1,
|
||||
output [1:0] VGA_SL,
|
||||
output VGA_SCALER, // Force VGA scaler
|
||||
|
||||
input [11:0] HDMI_WIDTH,
|
||||
input [11:0] HDMI_HEIGHT,
|
||||
|
||||
`ifdef USE_FB
|
||||
input [11:0] HDMI_WIDTH,
|
||||
input [11:0] HDMI_HEIGHT,
|
||||
output HDMI_FREEZE,
|
||||
|
||||
`ifdef MISTER_FB
|
||||
// Use framebuffer in DDRAM (USE_FB=1 in qsf)
|
||||
// FB_FORMAT:
|
||||
// [2:0] : 011=8bpp(palette) 100=16bpp 101=24bpp 110=32bpp
|
||||
|
@ -74,6 +75,7 @@ module emu
|
|||
input FB_LL,
|
||||
output FB_FORCE_BLANK,
|
||||
|
||||
`ifdef MISTER_FB_PALETTE
|
||||
// Palette control for 8bit modes.
|
||||
// Ignored for other video modes.
|
||||
output FB_PAL_CLK,
|
||||
|
@ -81,6 +83,7 @@ module emu
|
|||
output [23:0] FB_PAL_DOUT,
|
||||
input [23:0] FB_PAL_DIN,
|
||||
output FB_PAL_WR,
|
||||
`endif
|
||||
`endif
|
||||
|
||||
output LED_USER, // 1 - ON, 0 - OFF.
|
||||
|
@ -112,7 +115,6 @@ module emu
|
|||
output SD_CS,
|
||||
input SD_CD,
|
||||
|
||||
`ifdef USE_DDRAM
|
||||
//High latency DDR3 RAM interface
|
||||
//Use for non-critical time purposes
|
||||
output DDRAM_CLK,
|
||||
|
@ -125,9 +127,7 @@ module emu
|
|||
output [63:0] DDRAM_DIN,
|
||||
output [7:0] DDRAM_BE,
|
||||
output DDRAM_WE,
|
||||
`endif
|
||||
|
||||
`ifdef USE_SDRAM
|
||||
//SDRAM interface with lower latency
|
||||
output SDRAM_CLK,
|
||||
output SDRAM_CKE,
|
||||
|
@ -140,10 +140,10 @@ module emu
|
|||
output SDRAM_nCAS,
|
||||
output SDRAM_nRAS,
|
||||
output SDRAM_nWE,
|
||||
`endif
|
||||
|
||||
`ifdef DUAL_SDRAM
|
||||
`ifdef MISTER_DUAL_SDRAM
|
||||
//Secondary SDRAM
|
||||
//Set all output SDRAM_* signals to Z ASAP if SDRAM2_EN is 0
|
||||
input SDRAM2_EN,
|
||||
output SDRAM2_CLK,
|
||||
output [12:0] SDRAM2_A,
|
||||
|
@ -184,6 +184,7 @@ assign LED_DISK = 0;
|
|||
assign LED_POWER = 0;
|
||||
assign BUTTONS = 0;
|
||||
assign VGA_SCALER= 0;
|
||||
assign HDMI_FREEZE = 0;
|
||||
|
||||
wire [1:0] ar = status[8:7];
|
||||
video_freak video_freak
|
||||
|
@ -265,13 +266,13 @@ end
|
|||
// the status register is controlled by the on screen display (OSD)
|
||||
wire [31:0] status;
|
||||
wire [1:0] buttons;
|
||||
wire [31:0] sd_lba;
|
||||
wire [31:0] sd_lba[2];
|
||||
wire [1:0] sd_rd;
|
||||
wire [1:0] sd_wr;
|
||||
wire sd_ack;
|
||||
wire [1:0] sd_ack;
|
||||
wire [7:0] sd_buff_addr;
|
||||
wire [15:0] sd_buff_dout;
|
||||
wire [15:0] sd_buff_din;
|
||||
wire [15:0] sd_buff_din[2];
|
||||
wire sd_buff_wr;
|
||||
wire [1:0] img_mounted;
|
||||
wire [31:0] img_size;
|
||||
|
@ -288,13 +289,11 @@ wire [15:0] ioctl_data;
|
|||
|
||||
wire [32:0] TIMESTAMP;
|
||||
|
||||
hps_io #(.STRLEN($size(CONF_STR)>>3), .VDNUM(2), .WIDE(1)) hps_io
|
||||
hps_io #(.CONF_STR(CONF_STR), .VDNUM(2), .WIDE(1)) hps_io
|
||||
(
|
||||
.clk_sys(clk_sys),
|
||||
.HPS_BUS(HPS_BUS),
|
||||
|
||||
.conf_str(CONF_STR),
|
||||
|
||||
.buttons(buttons),
|
||||
.status(status),
|
||||
|
||||
|
@ -303,7 +302,6 @@ hps_io #(.STRLEN($size(CONF_STR)>>3), .VDNUM(2), .WIDE(1)) hps_io
|
|||
.sd_wr(sd_wr),
|
||||
.sd_ack(sd_ack),
|
||||
|
||||
.sd_conf(0),
|
||||
.sd_buff_addr(sd_buff_addr),
|
||||
.sd_buff_dout(sd_buff_dout),
|
||||
.sd_buff_din(sd_buff_din),
|
||||
|
@ -689,14 +687,16 @@ dataController_top dc0
|
|||
// block device interface for scsi disk
|
||||
.img_mounted(img_mounted),
|
||||
.img_size(img_size),
|
||||
.io_lba(sd_lba),
|
||||
.io_lba0(sd_lba[0]),
|
||||
.io_lba1(sd_lba[1]),
|
||||
.io_rd(sd_rd),
|
||||
.io_wr(sd_wr),
|
||||
.io_ack(sd_ack),
|
||||
|
||||
.sd_buff_addr(sd_buff_addr),
|
||||
.sd_buff_dout(sd_buff_dout),
|
||||
.sd_buff_din(sd_buff_din),
|
||||
.sd_buff_din0(sd_buff_din[0]),
|
||||
.sd_buff_din1(sd_buff_din[1]),
|
||||
.sd_buff_wr(sd_buff_wr)
|
||||
);
|
||||
|
||||
|
|
|
@ -81,13 +81,15 @@ module dataController_top(
|
|||
// connections to io controller
|
||||
input [1:0] img_mounted,
|
||||
input [31:0] img_size,
|
||||
output [31:0] io_lba,
|
||||
output [31:0] io_lba0,
|
||||
output [31:0] io_lba1,
|
||||
output [1:0] io_rd,
|
||||
output [1:0] io_wr,
|
||||
input io_ack,
|
||||
input [1:0] io_ack,
|
||||
input [7:0] sd_buff_addr,
|
||||
input [15:0] sd_buff_dout,
|
||||
output [15:0] sd_buff_din,
|
||||
output [15:0] sd_buff_din0,
|
||||
output [15:0] sd_buff_din1,
|
||||
input sd_buff_wr
|
||||
);
|
||||
|
||||
|
@ -179,14 +181,16 @@ module dataController_top(
|
|||
// connections to io controller
|
||||
.img_mounted( img_mounted ),
|
||||
.img_size( img_size ),
|
||||
.io_lba ( io_lba ),
|
||||
.io_lba0 ( io_lba0 ),
|
||||
.io_lba1 ( io_lba1 ),
|
||||
.io_rd ( io_rd ),
|
||||
.io_wr ( io_wr ),
|
||||
.io_ack ( io_ack ),
|
||||
|
||||
.sd_buff_addr(sd_buff_addr),
|
||||
.sd_buff_dout(sd_buff_dout),
|
||||
.sd_buff_din(sd_buff_din),
|
||||
.sd_buff_din0(sd_buff_din0),
|
||||
.sd_buff_din1(sd_buff_din1),
|
||||
.sd_buff_wr(sd_buff_wr)
|
||||
);
|
||||
|
||||
|
|
|
@ -65,15 +65,16 @@ module ncr5380
|
|||
input [1:0] img_mounted,
|
||||
input [31:0] img_size,
|
||||
|
||||
output [15:0] io_req_type,
|
||||
output [31:0] io_lba,
|
||||
output [31:0] io_lba0,
|
||||
output [31:0] io_lba1,
|
||||
output [1:0] io_rd,
|
||||
output [1:0] io_wr,
|
||||
input io_ack,
|
||||
input [1:0] io_ack,
|
||||
|
||||
input [7:0] sd_buff_addr,
|
||||
input [15:0] sd_buff_dout,
|
||||
output [15:0] sd_buff_din,
|
||||
output [15:0] sd_buff_din0,
|
||||
output [15:0] sd_buff_din1,
|
||||
input sd_buff_wr
|
||||
);
|
||||
|
||||
|
@ -278,17 +279,10 @@ module ncr5380
|
|||
scsi6_bsy ? scsi6_dout :
|
||||
8'h55;
|
||||
|
||||
assign io_lba = (scsi2_bsy) ? io_lba_2 : io_lba_6;
|
||||
assign sd_buff_din = (scsi2_bsy) ? sd_buff_din_2 : sd_buff_din_6;
|
||||
assign io_req_type = 16'h0000; // Not used atm. Could be used for CD-ROM sector requests later. ElectronAsh.
|
||||
|
||||
// input signals from target 2
|
||||
wire scsi2_bsy, scsi2_msg, scsi2_io, scsi2_cd, scsi2_req;
|
||||
wire [7:0] scsi2_dout;
|
||||
|
||||
wire [31:0] io_lba_2;
|
||||
wire [15:0] sd_buff_din_2;
|
||||
|
||||
// connect a target
|
||||
scsi #(.ID(2)) scsi2
|
||||
(
|
||||
|
@ -312,15 +306,15 @@ module ncr5380
|
|||
// to sd card
|
||||
.img_mounted(img_mounted[1]),
|
||||
.img_blocks(img_size[31:9]),
|
||||
.io_lba ( io_lba_2 ),
|
||||
.io_lba ( io_lba1 ),
|
||||
.io_rd ( io_rd[1] ),
|
||||
.io_wr ( io_wr[1] ),
|
||||
.io_ack ( io_ack & scsi2_bsy ),
|
||||
.io_ack ( io_ack[1] ),
|
||||
|
||||
.sd_buff_addr( sd_buff_addr ),
|
||||
.sd_buff_dout( sd_buff_dout ),
|
||||
.sd_buff_din( sd_buff_din_2 ),
|
||||
.sd_buff_wr( sd_buff_wr & scsi2_bsy )
|
||||
.sd_buff_din( sd_buff_din1 ),
|
||||
.sd_buff_wr( sd_buff_wr )
|
||||
);
|
||||
|
||||
|
||||
|
@ -328,9 +322,6 @@ module ncr5380
|
|||
wire scsi6_bsy, scsi6_msg, scsi6_io, scsi6_cd, scsi6_req;
|
||||
wire [7:0] scsi6_dout;
|
||||
|
||||
wire [31:0] io_lba_6;
|
||||
wire [15:0] sd_buff_din_6;
|
||||
|
||||
scsi #(.ID(6)) scsi6
|
||||
(
|
||||
.clk ( clk ) , // input clk
|
||||
|
@ -353,15 +344,15 @@ module ncr5380
|
|||
// to sd card
|
||||
.img_mounted( img_mounted[0] ),
|
||||
.img_blocks( img_size[31:9] ),
|
||||
.io_lba ( io_lba_6 ) , // output [31:0] io_lba
|
||||
.io_lba ( io_lba0 ) , // output [31:0] io_lba
|
||||
.io_rd ( io_rd[0] ) , // output io_rd
|
||||
.io_wr ( io_wr[0] ) , // output io_wr
|
||||
.io_ack ( io_ack & scsi6_bsy ) , // input io_ack
|
||||
.io_ack ( io_ack[0] ) , // input io_ack
|
||||
|
||||
.sd_buff_addr( sd_buff_addr ) , // input [8:0] sd_buff_addr
|
||||
.sd_buff_dout( sd_buff_dout ) , // input [7:0] sd_buff_dout
|
||||
.sd_buff_din( sd_buff_din_6 ) , // output [7:0] sd_buff_din
|
||||
.sd_buff_wr( sd_buff_wr & scsi6_bsy ) // input sd_buff_wr
|
||||
.sd_buff_din( sd_buff_din0 ) , // output [7:0] sd_buff_din
|
||||
.sd_buff_wr( sd_buff_wr ) // input sd_buff_wr
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -61,10 +61,10 @@ always @(posedge clk) sd_buff_din[15:8] <= buffer_out1[sd_buff_addr];
|
|||
// ---------------- buffer write engine ----------------------
|
||||
// the buffer itself. Can hold one sector
|
||||
reg [7:0] buffer_in0 [256];
|
||||
always @(posedge clk) if(sd_buff_wr) buffer_in0[sd_buff_addr] <= sd_buff_dout[7:0];
|
||||
always @(posedge clk) if(sd_buff_wr & io_ack) buffer_in0[sd_buff_addr] <= sd_buff_dout[7:0];
|
||||
|
||||
reg [7:0] buffer_in1 [256];
|
||||
always @(posedge clk) if(sd_buff_wr) buffer_in1[sd_buff_addr] <= sd_buff_dout[15:8];
|
||||
always @(posedge clk) if(sd_buff_wr & io_ack) buffer_in1[sd_buff_addr] <= sd_buff_dout[15:8];
|
||||
|
||||
// -----------------------------------------------------------
|
||||
|
||||
|
|
|
@ -174,15 +174,17 @@ module screen_rotate
|
|||
|
||||
input rotate_ccw,
|
||||
input no_rotate,
|
||||
input flip,
|
||||
output video_rotated,
|
||||
|
||||
output FB_EN,
|
||||
output [4:0] FB_FORMAT,
|
||||
output [11:0] FB_WIDTH,
|
||||
output [11:0] FB_HEIGHT,
|
||||
output [31:0] FB_BASE,
|
||||
output [13:0] FB_STRIDE,
|
||||
input FB_VBL,
|
||||
input FB_LL,
|
||||
output FB_EN,
|
||||
output [4:0] FB_FORMAT,
|
||||
output reg [11:0] FB_WIDTH,
|
||||
output reg [11:0] FB_HEIGHT,
|
||||
output [31:0] FB_BASE,
|
||||
output [13:0] FB_STRIDE,
|
||||
input FB_VBL,
|
||||
input FB_LL,
|
||||
|
||||
output DDRAM_CLK,
|
||||
input DDRAM_BUSY,
|
||||
|
@ -196,6 +198,8 @@ module screen_rotate
|
|||
|
||||
parameter MEM_BASE = 7'b0010010; // buffer at 0x24000000, 3x8MB
|
||||
|
||||
reg do_flip;
|
||||
|
||||
assign DDRAM_CLK = CLK_VIDEO;
|
||||
assign DDRAM_BURSTCNT = 1;
|
||||
assign DDRAM_ADDR = {MEM_BASE, i_fb, ram_addr[22:3]};
|
||||
|
@ -207,8 +211,6 @@ assign DDRAM_RD = 0;
|
|||
assign FB_EN = fb_en[2];
|
||||
assign FB_FORMAT = 5'b00110;
|
||||
assign FB_BASE = {MEM_BASE,o_fb,23'd0};
|
||||
assign FB_WIDTH = vsz;
|
||||
assign FB_HEIGHT = hsz;
|
||||
assign FB_STRIDE = stride;
|
||||
|
||||
function [1:0] buf_next;
|
||||
|
@ -220,6 +222,19 @@ function [1:0] buf_next;
|
|||
end
|
||||
endfunction
|
||||
|
||||
assign video_rotated = ~no_rotate;
|
||||
|
||||
always @(posedge CLK_VIDEO) begin
|
||||
do_flip <= no_rotate && flip;
|
||||
if( do_flip ) begin
|
||||
FB_WIDTH <= hsz;
|
||||
FB_HEIGHT <= vsz;
|
||||
end else begin
|
||||
FB_WIDTH <= vsz;
|
||||
FB_HEIGHT <= hsz;
|
||||
end
|
||||
end
|
||||
|
||||
reg [1:0] i_fb,o_fb;
|
||||
always @(posedge CLK_VIDEO) begin
|
||||
reg old_vbl,old_vs;
|
||||
|
@ -251,20 +266,23 @@ always @(posedge CLK_VIDEO) begin
|
|||
if(CE_PIXEL) begin
|
||||
old_vs <= VGA_VS;
|
||||
old_de <= VGA_DE;
|
||||
|
||||
|
||||
hcnt <= hcnt + 1'd1;
|
||||
if(~old_de & VGA_DE) begin
|
||||
hcnt <= 1;
|
||||
vcnt <= vcnt + 1'd1;
|
||||
end
|
||||
if(old_de & ~VGA_DE) hsz <= hcnt;
|
||||
if(old_de & ~VGA_DE) begin
|
||||
hsz <= hcnt;
|
||||
if( do_flip ) bwidth <= hcnt + 2'd3;
|
||||
end
|
||||
if(~old_vs & VGA_VS) begin
|
||||
vsz <= vcnt;
|
||||
bwidth <= vcnt + 2'd3;
|
||||
if( !do_flip ) bwidth <= vcnt + 2'd3;
|
||||
vcnt <= 0;
|
||||
fb_en <= {fb_en[1:0], ~no_rotate};
|
||||
fb_en <= {fb_en[1:0], ~no_rotate | flip};
|
||||
end
|
||||
if(old_vs & ~VGA_VS) bufsize <= hsz * stride;
|
||||
if(old_vs & ~VGA_VS) bufsize <= (do_flip ? vsz : hsz ) * stride;
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -278,21 +296,25 @@ always @(posedge CLK_VIDEO) begin
|
|||
reg old_vs, old_de;
|
||||
|
||||
ram_wr <= 0;
|
||||
if(CE_PIXEL) begin
|
||||
if(CE_PIXEL && FB_EN) begin
|
||||
old_vs <= VGA_VS;
|
||||
old_de <= VGA_DE;
|
||||
|
||||
if(~old_vs & VGA_VS) begin
|
||||
next_addr <= rotate_ccw ? (bufsize - stride) : {vsz-1'd1, 2'b00};
|
||||
next_addr <=
|
||||
do_flip ? bufsize-3'd4 :
|
||||
rotate_ccw ? (bufsize - stride) : {vsz-1'd1, 2'b00};
|
||||
hcnt <= rotate_ccw ? 3'd4 : {vsz-2'd2, 2'b00};
|
||||
end
|
||||
if(VGA_DE) begin
|
||||
ram_wr <= 1;
|
||||
ram_data <= {VGA_B,VGA_G,VGA_R};
|
||||
ram_data <= {8'd0,VGA_B,VGA_G,VGA_R};
|
||||
ram_addr <= next_addr;
|
||||
next_addr <= rotate_ccw ? (next_addr - stride) : (next_addr + stride);
|
||||
next_addr <=
|
||||
do_flip ? next_addr-3'd4 :
|
||||
rotate_ccw ? (next_addr - stride) : (next_addr + stride);
|
||||
end
|
||||
if(old_de & ~VGA_DE) begin
|
||||
if(old_de & ~VGA_DE & ~do_flip) begin
|
||||
next_addr <= rotate_ccw ? (bufsize - stride + hcnt) : hcnt;
|
||||
hcnt <= rotate_ccw ? (hcnt + 3'd4) : (hcnt - 3'd4);
|
||||
end
|
||||
|
|
936
sys/ascal.vhd
936
sys/ascal.vhd
File diff suppressed because it is too large
Load Diff
|
@ -24,14 +24,13 @@
|
|||
// Use buffer to access SD card. It's time-critical part.
|
||||
//
|
||||
// WIDE=1 for 16 bit file I/O
|
||||
// VDNUM 1-4
|
||||
module hps_io #(parameter STRLEN=0, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0)
|
||||
// VDNUM 1..10
|
||||
// BLKSZ 0..7: 0 = 128, 1 = 256, 2 = 512(default), .. 7 = 16384
|
||||
//
|
||||
module hps_io #(parameter CONF_STR, CONF_STR_BRAM=1, PS2DIV=0, WIDE=0, VDNUM=1, BLKSZ=2, PS2WE=0)
|
||||
(
|
||||
input clk_sys,
|
||||
inout [45:0] HPS_BUS,
|
||||
|
||||
// parameter STRLEN and the actual length of conf_str have to match
|
||||
input [(8*STRLEN)-1:0] conf_str,
|
||||
inout [48:0] HPS_BUS,
|
||||
|
||||
// buttons up to 32
|
||||
output reg [31:0] joystick_0,
|
||||
|
@ -42,12 +41,19 @@ module hps_io #(parameter STRLEN=0, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0)
|
|||
output reg [31:0] joystick_5,
|
||||
|
||||
// analog -127..+127, Y: [15:8], X: [7:0]
|
||||
output reg [15:0] joystick_analog_0,
|
||||
output reg [15:0] joystick_analog_1,
|
||||
output reg [15:0] joystick_analog_2,
|
||||
output reg [15:0] joystick_analog_3,
|
||||
output reg [15:0] joystick_analog_4,
|
||||
output reg [15:0] joystick_analog_5,
|
||||
output reg [15:0] joystick_l_analog_0,
|
||||
output reg [15:0] joystick_l_analog_1,
|
||||
output reg [15:0] joystick_l_analog_2,
|
||||
output reg [15:0] joystick_l_analog_3,
|
||||
output reg [15:0] joystick_l_analog_4,
|
||||
output reg [15:0] joystick_l_analog_5,
|
||||
|
||||
output reg [15:0] joystick_r_analog_0,
|
||||
output reg [15:0] joystick_r_analog_1,
|
||||
output reg [15:0] joystick_r_analog_2,
|
||||
output reg [15:0] joystick_r_analog_3,
|
||||
output reg [15:0] joystick_r_analog_4,
|
||||
output reg [15:0] joystick_r_analog_5,
|
||||
|
||||
// paddle 0..255
|
||||
output reg [7:0] paddle_0,
|
||||
|
@ -68,6 +74,10 @@ module hps_io #(parameter STRLEN=0, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0)
|
|||
output [1:0] buttons,
|
||||
output forced_scandoubler,
|
||||
output direct_video,
|
||||
input video_rotated,
|
||||
|
||||
//toggle to force notify of video mode change
|
||||
input new_vmode,
|
||||
|
||||
output reg [63:0] status,
|
||||
input [63:0] status_in,
|
||||
|
@ -77,31 +87,23 @@ module hps_io #(parameter STRLEN=0, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0)
|
|||
input info_req,
|
||||
input [7:0] info,
|
||||
|
||||
//toggle to force notify of video mode change
|
||||
input new_vmode,
|
||||
|
||||
// SD config
|
||||
output reg [VD:0] img_mounted, // signaling that new image has been mounted
|
||||
output reg img_readonly, // mounted as read only. valid only for active bit in img_mounted
|
||||
output reg [63:0] img_size, // size of image in bytes. valid only for active bit in img_mounted
|
||||
|
||||
// SD block level access
|
||||
input [31:0] sd_lba,
|
||||
input [VD:0] sd_rd, // only single sd_rd can be active at any given time
|
||||
input [VD:0] sd_wr, // only single sd_wr can be active at any given time
|
||||
output reg sd_ack,
|
||||
|
||||
// do not use in new projects.
|
||||
// CID and CSD are fake except CSD image size field.
|
||||
input sd_conf,
|
||||
output reg sd_ack_conf,
|
||||
input [31:0] sd_lba[VDNUM],
|
||||
input [5:0] sd_blk_cnt[VDNUM], // number of blocks-1, total size ((sd_blk_cnt+1)*(1<<(BLKSZ+7))) must be <= 16384!
|
||||
input [VD:0] sd_rd,
|
||||
input [VD:0] sd_wr,
|
||||
output reg [VD:0] sd_ack,
|
||||
|
||||
// SD byte level access. Signals for 2-PORT altsyncram.
|
||||
output reg [AW:0] sd_buff_addr,
|
||||
output reg [DW:0] sd_buff_dout,
|
||||
input [DW:0] sd_buff_din,
|
||||
input [DW:0] sd_buff_din[VDNUM],
|
||||
output reg sd_buff_wr,
|
||||
input [15:0] sd_req_type,
|
||||
|
||||
// ARM -> FPGA download
|
||||
output reg ioctl_download = 0, // signal indicating an active download
|
||||
|
@ -110,6 +112,8 @@ module hps_io #(parameter STRLEN=0, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0)
|
|||
output reg [26:0] ioctl_addr, // in WIDE mode address will be incremented by 2
|
||||
output reg [DW:0] ioctl_dout,
|
||||
output reg ioctl_upload = 0, // signal indicating an active upload
|
||||
input ioctl_upload_req, // request to save (must be supported on HPS side for specific core)
|
||||
input [7:0] ioctl_upload_index,
|
||||
input [DW:0] ioctl_din,
|
||||
output reg ioctl_rd,
|
||||
output reg [31:0] ioctl_file_ext,
|
||||
|
@ -161,10 +165,8 @@ module hps_io #(parameter STRLEN=0, PS2DIV=0, WIDE=0, VDNUM=1, PS2WE=0)
|
|||
assign EXT_BUS[31:16] = HPS_BUS[31:16];
|
||||
assign EXT_BUS[35:33] = HPS_BUS[35:33];
|
||||
|
||||
localparam MAX_W = $clog2((512 > (STRLEN+1)) ? 512 : (STRLEN+1))-1;
|
||||
|
||||
localparam DW = (WIDE) ? 15 : 7;
|
||||
localparam AW = (WIDE) ? 7 : 8;
|
||||
localparam AW = (WIDE) ? 12 : 13;
|
||||
localparam VD = VDNUM-1;
|
||||
|
||||
wire io_strobe= HPS_BUS[33];
|
||||
|
@ -187,22 +189,18 @@ assign forced_scandoubler = cfg[4];
|
|||
//cfg[5] - ypbpr handled in sys_top
|
||||
assign direct_video = cfg[10];
|
||||
|
||||
// command byte read by the io controller
|
||||
wire [15:0] sd_cmd =
|
||||
{
|
||||
2'b00,
|
||||
(VDNUM>=4) ? sd_wr[3] : 1'b0,
|
||||
(VDNUM>=3) ? sd_wr[2] : 1'b0,
|
||||
(VDNUM>=2) ? sd_wr[1] : 1'b0,
|
||||
reg [3:0] sdn;
|
||||
reg [3:0] sd_rrb = 0;
|
||||
always_comb begin
|
||||
int n, i;
|
||||
|
||||
(VDNUM>=4) ? sd_rd[3] : 1'b0,
|
||||
(VDNUM>=3) ? sd_rd[2] : 1'b0,
|
||||
(VDNUM>=2) ? sd_rd[1] : 1'b0,
|
||||
|
||||
4'h5, sd_conf, 1'b1,
|
||||
sd_wr[0],
|
||||
sd_rd[0]
|
||||
};
|
||||
sdn = 0;
|
||||
for(i = VDNUM - 1; i >= 0; i = i - 1) begin
|
||||
n = i + sd_rrb;
|
||||
if(n >= VDNUM) n = n - VDNUM;
|
||||
if(sd_wr[n] | sd_rd[n]) sdn = n[3:0];
|
||||
end
|
||||
end
|
||||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
|
@ -219,6 +217,7 @@ video_calc video_calc
|
|||
.vs_hdmi(HPS_BUS[44]),
|
||||
.f1(HPS_BUS[45]),
|
||||
.new_vmode(new_vmode),
|
||||
.video_rotated(video_rotated),
|
||||
|
||||
.par_num(byte_cnt[3:0]),
|
||||
.dout(vc_dout)
|
||||
|
@ -226,6 +225,19 @@ video_calc video_calc
|
|||
|
||||
/////////////////////////////////////////////////////////
|
||||
|
||||
localparam STRLEN = $size(CONF_STR)>>3;
|
||||
localparam MAX_W = $clog2((32 > (STRLEN+2)) ? 32 : (STRLEN+2))-1;
|
||||
|
||||
wire [7:0] conf_byte;
|
||||
generate
|
||||
if(CONF_STR_BRAM) begin
|
||||
confstr_rom #(CONF_STR, STRLEN) confstr_rom(.*, .conf_addr(byte_cnt - 1'd1));
|
||||
end
|
||||
else begin
|
||||
assign conf_byte = CONF_STR[{(STRLEN - byte_cnt),3'b000} +:8];
|
||||
end
|
||||
endgenerate
|
||||
|
||||
assign gamma_bus[20:0] = {clk_sys, gamma_en, gamma_wr, gamma_wr_addr, gamma_value};
|
||||
reg gamma_en;
|
||||
reg gamma_wr;
|
||||
|
@ -237,6 +249,8 @@ wire pressed = (ps2_key_raw[15:8] != 8'hf0);
|
|||
wire extended = (~pressed ? (ps2_key_raw[23:16] == 8'he0) : (ps2_key_raw[15:8] == 8'he0));
|
||||
|
||||
reg [MAX_W:0] byte_cnt;
|
||||
reg [3:0] sdn_ack;
|
||||
wire [15:0] disk = 16'd1 << io_din[11:8];
|
||||
|
||||
always@(posedge clk_sys) begin : uio_block
|
||||
reg [15:0] cmd;
|
||||
|
@ -247,16 +261,22 @@ always@(posedge clk_sys) begin : uio_block
|
|||
reg [3:0] stflg = 0;
|
||||
reg [63:0] status_req;
|
||||
reg old_status_set = 0;
|
||||
reg old_upload_req = 0;
|
||||
reg upload_req = 0;
|
||||
reg old_info = 0;
|
||||
reg [7:0] info_n = 0;
|
||||
reg [15:0] tmp1;
|
||||
reg [7:0] tmp2;
|
||||
reg [3:0] sdn_r;
|
||||
|
||||
old_status_set <= status_set;
|
||||
if(~old_status_set & status_set) begin
|
||||
stflg <= stflg + 1'd1;
|
||||
status_req <= status_in;
|
||||
end
|
||||
|
||||
old_upload_req <= ioctl_upload_req;
|
||||
if(~old_upload_req & ioctl_upload_req) upload_req <= 1;
|
||||
|
||||
old_info <= info_req;
|
||||
if(~old_info & info_req) info_n <= info;
|
||||
|
@ -282,7 +302,6 @@ always@(posedge clk_sys) begin : uio_block
|
|||
cmd <= 0;
|
||||
byte_cnt <= 0;
|
||||
sd_ack <= 0;
|
||||
sd_ack_conf <= 0;
|
||||
io_dout <= 0;
|
||||
ps2skip <= 0;
|
||||
img_mounted <= 0;
|
||||
|
@ -295,23 +314,29 @@ always@(posedge clk_sys) begin : uio_block
|
|||
if(byte_cnt == 0) begin
|
||||
cmd <= io_din;
|
||||
|
||||
case(io_din)
|
||||
'h19: sd_ack_conf <= 1;
|
||||
'h17,
|
||||
'h18: sd_ack <= 1;
|
||||
'h29: io_dout <= {4'hA, stflg};
|
||||
'h2B: io_dout <= 1;
|
||||
'h2F: io_dout <= 1;
|
||||
'h32: io_dout <= gamma_bus[21];
|
||||
'h36: begin io_dout <= info_n; info_n <= 0; end
|
||||
'h39: io_dout <= 1;
|
||||
casex(io_din)
|
||||
'h16: begin io_dout <= {1'b1, sd_blk_cnt[sdn], BLKSZ[2:0], sdn, sd_wr[sdn], sd_rd[sdn]}; sdn_r <= sdn; end
|
||||
'h0X17,
|
||||
'h0X18: begin sd_ack <= disk[VD:0]; sdn_ack <= io_din[11:8]; end
|
||||
'h29: io_dout <= {4'hA, stflg};
|
||||
`ifdef MISTER_DISABLE_ADAPTIVE
|
||||
'h2B: io_dout <= {HPS_BUS[48:46],4'b0110};
|
||||
`else
|
||||
'h2B: io_dout <= {HPS_BUS[48:46],4'b0111};
|
||||
`endif
|
||||
'h2F: io_dout <= 1;
|
||||
'h32: io_dout <= gamma_bus[21];
|
||||
'h36: begin io_dout <= info_n; info_n <= 0; end
|
||||
'h39: io_dout <= 1;
|
||||
'h3C: if(upload_req) begin io_dout <= {ioctl_upload_index, 8'd1}; upload_req <= 0; end
|
||||
'h3E: io_dout <= 1; // shadow mask
|
||||
endcase
|
||||
|
||||
sd_buff_addr <= 0;
|
||||
if(io_din == 5) ps2_key_raw <= 0;
|
||||
end else begin
|
||||
|
||||
case(cmd)
|
||||
casex(cmd)
|
||||
// buttons and switches
|
||||
'h01: cfg <= io_din;
|
||||
'h02: if(byte_cnt==1) joystick_0[15:0] <= io_din; else joystick_0[31:16] <= io_din;
|
||||
|
@ -353,47 +378,41 @@ always@(posedge clk_sys) begin : uio_block
|
|||
end
|
||||
|
||||
// reading config string, returning a byte from string
|
||||
'h14: if(byte_cnt < STRLEN + 1) io_dout[7:0] <= conf_str[(STRLEN - byte_cnt)<<3 +:8];
|
||||
'h14: if(byte_cnt <= STRLEN) io_dout[7:0] <= conf_byte;
|
||||
|
||||
// reading sd card status
|
||||
'h16: if(!byte_cnt[MAX_W:3]) begin
|
||||
case(byte_cnt[2:0])
|
||||
1: io_dout <= sd_cmd;
|
||||
2: io_dout <= sd_lba[15:0];
|
||||
3: io_dout <= sd_lba[31:16];
|
||||
4: io_dout <= sd_req_type;
|
||||
'h16: if(!byte_cnt[MAX_W:2]) begin
|
||||
case(byte_cnt[1:0])
|
||||
1: sd_rrb <= (sd_rrb == VD) ? 4'd0 : (sd_rrb + 1'd1);
|
||||
2: io_dout <= sd_lba[sdn_r][15:0];
|
||||
3: io_dout <= sd_lba[sdn_r][31:16];
|
||||
endcase
|
||||
end
|
||||
|
||||
// send SD config IO -> FPGA
|
||||
// flag that download begins
|
||||
// sd card knows data is config if sd_dout_strobe is asserted
|
||||
// with sd_ack still being inactive (low)
|
||||
'h19,
|
||||
// send sector IO -> FPGA
|
||||
// flag that download begins
|
||||
'h17: begin
|
||||
'h0X17: begin
|
||||
sd_buff_dout <= io_din[DW:0];
|
||||
b_wr <= 1;
|
||||
end
|
||||
|
||||
// reading sd card write data
|
||||
'h18: begin
|
||||
'h0X18: begin
|
||||
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
|
||||
io_dout <= sd_buff_din;
|
||||
io_dout <= sd_buff_din[sdn_ack];
|
||||
end
|
||||
|
||||
// joystick analog
|
||||
// joystick left analog
|
||||
'h1a: if(!byte_cnt[MAX_W:2]) begin
|
||||
case(byte_cnt[1:0])
|
||||
1: {pdsp_idx,stick_idx} <= io_din[7:0]; // first byte is joystick index
|
||||
2: case(stick_idx)
|
||||
0: joystick_analog_0 <= io_din;
|
||||
1: joystick_analog_1 <= io_din;
|
||||
2: joystick_analog_2 <= io_din;
|
||||
3: joystick_analog_3 <= io_din;
|
||||
4: joystick_analog_4 <= io_din;
|
||||
5: joystick_analog_5 <= io_din;
|
||||
0: joystick_l_analog_0 <= io_din;
|
||||
1: joystick_l_analog_1 <= io_din;
|
||||
2: joystick_l_analog_2 <= io_din;
|
||||
3: joystick_l_analog_3 <= io_din;
|
||||
4: joystick_l_analog_4 <= io_din;
|
||||
5: joystick_l_analog_5 <= io_din;
|
||||
15: case(pdsp_idx)
|
||||
0: paddle_0 <= io_din[7:0];
|
||||
1: paddle_1 <= io_din[7:0];
|
||||
|
@ -412,6 +431,21 @@ always@(posedge clk_sys) begin : uio_block
|
|||
endcase
|
||||
end
|
||||
|
||||
// joystick right analog
|
||||
'h3d: if(!byte_cnt[MAX_W:2]) begin
|
||||
case(byte_cnt[1:0])
|
||||
1: stick_idx <= io_din[3:0]; // first byte is joystick index
|
||||
2: case(stick_idx)
|
||||
0: joystick_r_analog_0 <= io_din;
|
||||
1: joystick_r_analog_1 <= io_din;
|
||||
2: joystick_r_analog_2 <= io_din;
|
||||
3: joystick_r_analog_3 <= io_din;
|
||||
4: joystick_r_analog_4 <= io_din;
|
||||
5: joystick_r_analog_5 <= io_din;
|
||||
endcase
|
||||
endcase
|
||||
end
|
||||
|
||||
// notify image selection
|
||||
'h1c: begin
|
||||
img_mounted <= io_din[VD:0] ? io_din[VD:0] : 1'b1;
|
||||
|
@ -815,6 +849,7 @@ module video_calc
|
|||
input vs_hdmi,
|
||||
input f1,
|
||||
input new_vmode,
|
||||
input video_rotated,
|
||||
|
||||
input [3:0] par_num,
|
||||
output reg [15:0] dout
|
||||
|
@ -822,7 +857,7 @@ module video_calc
|
|||
|
||||
always @(posedge clk_sys) begin
|
||||
case(par_num)
|
||||
1: dout <= {|vid_int, vid_nres};
|
||||
1: dout <= {video_rotated, |vid_int, vid_nres};
|
||||
2: dout <= vid_hcnt[15:0];
|
||||
3: dout <= vid_hcnt[31:16];
|
||||
4: dout <= vid_vcnt[15:0];
|
||||
|
@ -936,3 +971,16 @@ always @(posedge clk_100) begin
|
|||
end
|
||||
|
||||
endmodule
|
||||
|
||||
module confstr_rom #(parameter CONF_STR, STRLEN)
|
||||
(
|
||||
input clk_sys,
|
||||
input [$clog2(STRLEN+1)-1:0] conf_addr,
|
||||
output reg [7:0] conf_byte
|
||||
);
|
||||
|
||||
wire [7:0] rom[STRLEN];
|
||||
initial for(int i = 0; i < STRLEN; i++) rom[i] = CONF_STR[((STRLEN-i)*8)-1 -:8];
|
||||
always @ (posedge clk_sys) conf_byte <= rom[conf_addr];
|
||||
|
||||
endmodule
|
|
@ -72,7 +72,7 @@ always@(posedge clk_sys) begin
|
|||
// command 0x40: OSDCMDENABLE, OSDCMDDISABLE
|
||||
if(io_din[7:4] == 4) begin
|
||||
if(!io_din[0]) {osd_status,highres} <= 0;
|
||||
else {osd_status,info} <= {~io_din[2],io_din[2]};
|
||||
else {osd_status,info} <= {~io_din[2] & ~io_din[3],io_din[2]};
|
||||
bcnt <= 0;
|
||||
end
|
||||
// command 0x20: OSDCMDWRITE
|
||||
|
|
|
@ -5,11 +5,11 @@ module scanlines #(parameter v2=0)
|
|||
input [1:0] scanlines,
|
||||
input [23:0] din,
|
||||
input hs_in,vs_in,
|
||||
input de_in,
|
||||
input de_in,ce_in,
|
||||
|
||||
output reg [23:0] dout,
|
||||
output reg hs_out,vs_out,
|
||||
output reg de_out
|
||||
output reg de_out,ce_out
|
||||
);
|
||||
|
||||
reg [1:0] scanline;
|
||||
|
@ -56,12 +56,13 @@ end
|
|||
|
||||
always @(posedge clk) begin
|
||||
reg [23:0] dout1, dout2;
|
||||
reg de1,de2,vs1,vs2,hs1,hs2;
|
||||
reg de1,de2,vs1,vs2,hs1,hs2,ce1,ce2;
|
||||
|
||||
dout <= dout2; dout2 <= dout1; dout1 <= d;
|
||||
vs_out <= vs2; vs2 <= vs1; vs1 <= vs_in;
|
||||
hs_out <= hs2; hs2 <= hs1; hs1 <= hs_in;
|
||||
de_out <= de2; de2 <= de1; de1 <= de_in;
|
||||
ce_out <= ce2; ce2 <= ce1; ce1 <= ce_in;
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
|
798
sys/sd_card.sv
798
sys/sd_card.sv
|
@ -23,52 +23,55 @@
|
|||
|
||||
//
|
||||
// Made module syncrhronous. Total code refactoring. (Sorgelig)
|
||||
// clk_spi must be at least 4 x sck for proper work.
|
||||
// clk_spi must be at least 2 x sck for proper work.
|
||||
|
||||
module sd_card #(parameter WIDE = 0)
|
||||
module sd_card #(parameter WIDE = 0, OCTAL=0)
|
||||
(
|
||||
input clk_sys,
|
||||
input reset,
|
||||
input clk_sys,
|
||||
input reset,
|
||||
|
||||
input sdhc,
|
||||
|
||||
output [31:0] sd_lba,
|
||||
output reg sd_rd,
|
||||
output reg sd_wr,
|
||||
input sd_ack,
|
||||
input sd_ack_conf,
|
||||
input sdhc,
|
||||
input img_mounted,
|
||||
input [63:0] img_size,
|
||||
|
||||
input [AW:0] sd_buff_addr,
|
||||
input [DW:0] sd_buff_dout,
|
||||
output [DW:0] sd_buff_din,
|
||||
input sd_buff_wr,
|
||||
output reg [31:0] sd_lba,
|
||||
output reg sd_rd,
|
||||
output reg sd_wr,
|
||||
input sd_ack,
|
||||
|
||||
input [AW:0] sd_buff_addr,
|
||||
input [DW:0] sd_buff_dout,
|
||||
output [DW:0] sd_buff_din,
|
||||
input sd_buff_wr,
|
||||
|
||||
// SPI interface
|
||||
input clk_spi,
|
||||
input clk_spi,
|
||||
|
||||
input ss,
|
||||
input sck,
|
||||
input mosi,
|
||||
output reg miso
|
||||
input ss,
|
||||
input sck,
|
||||
input [SW:0] mosi,
|
||||
output reg [SW:0] miso
|
||||
);
|
||||
|
||||
localparam AW = WIDE ? 7 : 8;
|
||||
localparam DW = WIDE ? 15 : 7;
|
||||
localparam AW = WIDE ? 7 : 8;
|
||||
localparam DW = WIDE ? 15 : 7;
|
||||
localparam SZ = OCTAL ? 8 : 1;
|
||||
localparam SW = SZ-1;
|
||||
|
||||
assign sd_lba = sdhc ? lba : {9'd0, lba[31:9]};
|
||||
|
||||
wire[31:0] OCR = { 1'b1, sdhc, 30'd0 }; // bit30 = 1 -> high capaciry card (sdhc) // bit31 = 0 -> card power up finished
|
||||
wire [7:0] READ_DATA_TOKEN = 8'hfe;
|
||||
wire [7:0] DATA_TOKEN_CMD25 = 8'hfc;
|
||||
wire [7:0] STOP_TRAN = 8'hfd;
|
||||
wire [7:0] DATA_TOKEN = 8'hfe;
|
||||
wire [7:0] WRITE_DATA_RESPONSE = 8'h05;
|
||||
|
||||
// number of bytes to wait after a command before sending the reply
|
||||
localparam NCR=3;
|
||||
localparam NCR = 5+3; // 5 bytes are required (command length)
|
||||
|
||||
localparam RD_STATE_IDLE = 0;
|
||||
localparam RD_STATE_WAIT_IO = 1;
|
||||
localparam RD_STATE_SEND_TOKEN = 2;
|
||||
localparam RD_STATE_SEND_DATA = 3;
|
||||
localparam RD_STATE_WAIT_M = 4;
|
||||
localparam RD_STATE_START = 1;
|
||||
localparam RD_STATE_WAIT_IO = 2;
|
||||
localparam RD_STATE_SEND_TOKEN = 3;
|
||||
localparam RD_STATE_SEND_DATA = 4;
|
||||
localparam RD_STATE_WAIT_M = 5;
|
||||
|
||||
localparam WR_STATE_IDLE = 0;
|
||||
localparam WR_STATE_EXP_DTOKEN = 1;
|
||||
|
@ -78,460 +81,383 @@ localparam WR_STATE_RECV_CRC1 = 4;
|
|||
localparam WR_STATE_SEND_DRESP = 5;
|
||||
localparam WR_STATE_BUSY = 6;
|
||||
|
||||
sdbuf #(WIDE) buffer
|
||||
localparam PREF_STATE_IDLE = 0;
|
||||
localparam PREF_STATE_RD = 1;
|
||||
localparam PREF_STATE_FINISH = 2;
|
||||
|
||||
altsyncram sdbuf
|
||||
(
|
||||
.clock_a(clk_sys),
|
||||
.address_a(sd_buff_addr),
|
||||
.data_a(sd_buff_dout),
|
||||
.wren_a(sd_ack & sd_buff_wr),
|
||||
.q_a(sd_buff_din),
|
||||
.clock0 (clk_sys),
|
||||
.address_a ({sd_buf,sd_buff_addr}),
|
||||
.data_a (sd_buff_dout),
|
||||
.wren_a (sd_ack & sd_buff_wr),
|
||||
.q_a (sd_buff_din),
|
||||
|
||||
.clock_b(clk_spi),
|
||||
.address_b(buffer_ptr),
|
||||
.data_b(buffer_din),
|
||||
.wren_b(buffer_wr),
|
||||
.q_b(buffer_dout)
|
||||
.clock1 (clk_spi),
|
||||
.address_b ({spi_buf,buffer_ptr}),
|
||||
.data_b (buffer_din),
|
||||
.wren_b (buffer_wr),
|
||||
.q_b (buffer_dout),
|
||||
|
||||
.aclr0(1'b0),
|
||||
.aclr1(1'b0),
|
||||
.addressstall_a(1'b0),
|
||||
.addressstall_b(1'b0),
|
||||
.byteena_a(1'b1),
|
||||
.byteena_b(1'b1),
|
||||
.clocken0(1'b1),
|
||||
.clocken1(1'b1),
|
||||
.clocken2(1'b1),
|
||||
.clocken3(1'b1),
|
||||
.eccstatus(),
|
||||
.rden_a(1'b1),
|
||||
.rden_b(1'b1)
|
||||
);
|
||||
defparam
|
||||
sdbuf.numwords_a = 1<<(AW+3),
|
||||
sdbuf.widthad_a = AW+3,
|
||||
sdbuf.width_a = DW+1,
|
||||
sdbuf.numwords_b = 2048,
|
||||
sdbuf.widthad_b = 11,
|
||||
sdbuf.width_b = 8,
|
||||
sdbuf.address_reg_b = "CLOCK1",
|
||||
sdbuf.clock_enable_input_a = "BYPASS",
|
||||
sdbuf.clock_enable_input_b = "BYPASS",
|
||||
sdbuf.clock_enable_output_a = "BYPASS",
|
||||
sdbuf.clock_enable_output_b = "BYPASS",
|
||||
sdbuf.indata_reg_b = "CLOCK1",
|
||||
sdbuf.intended_device_family = "Cyclone V",
|
||||
sdbuf.lpm_type = "altsyncram",
|
||||
sdbuf.operation_mode = "BIDIR_DUAL_PORT",
|
||||
sdbuf.outdata_aclr_a = "NONE",
|
||||
sdbuf.outdata_aclr_b = "NONE",
|
||||
sdbuf.outdata_reg_a = "UNREGISTERED",
|
||||
sdbuf.outdata_reg_b = "UNREGISTERED",
|
||||
sdbuf.power_up_uninitialized = "FALSE",
|
||||
sdbuf.read_during_write_mode_port_a = "NEW_DATA_NO_NBE_READ",
|
||||
sdbuf.read_during_write_mode_port_b = "NEW_DATA_NO_NBE_READ",
|
||||
sdbuf.width_byteena_a = 1,
|
||||
sdbuf.width_byteena_b = 1,
|
||||
sdbuf.wrcontrol_wraddress_reg_b = "CLOCK1";
|
||||
|
||||
sdbuf #(WIDE) conf
|
||||
(
|
||||
.clock_a(clk_sys),
|
||||
.address_a(sd_buff_addr),
|
||||
.data_a(sd_buff_dout),
|
||||
.wren_a(sd_ack_conf & sd_buff_wr),
|
||||
reg [26:0] csd_size;
|
||||
reg csd_sdhc;
|
||||
always @(posedge clk_sys) begin
|
||||
if (img_mounted) begin
|
||||
csd_sdhc <= sdhc;
|
||||
if (sdhc) begin
|
||||
csd_size[0] <= 0;
|
||||
csd_size[22:1] <= img_size[40:19]; // in 512K units
|
||||
csd_size[26:23] <= 0;
|
||||
end
|
||||
else begin
|
||||
csd_size[2:0] <= 7; // C_SIZE_MULT
|
||||
csd_size[14:3] <= 12'b101101101101;
|
||||
csd_size[26:15] <= img_size[29:18]; // in 256K units ((2**(C_SIZE_MULT+2))*512)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
.clock_b(clk_spi),
|
||||
.address_b(buffer_ptr),
|
||||
.q_b(config_dout)
|
||||
);
|
||||
wire [127:0] CSD = {1'b0,csd_sdhc,6'h00,8'h0e,8'h00,8'h32,8'h5b,8'h59,6'h00,csd_size,7'h7f,8'h80,8'h0a,8'h40,8'h40,8'hf1};
|
||||
wire [127:0] CID = {8'hcd,8'hc7,8'h00,8'h93,8'h6f,8'h2f,8'h73,8'h00,8'h00,8'h44,8'h32,8'h38,8'h34,8'h00,8'h00,8'h3e};
|
||||
|
||||
reg [31:0] lba, new_lba;
|
||||
reg [8:0] buffer_ptr;
|
||||
reg [7:0] buffer_din;
|
||||
wire [7:0] buffer_dout;
|
||||
wire [7:0] config_dout;
|
||||
reg buffer_wr;
|
||||
|
||||
always @(posedge clk_spi) begin
|
||||
reg [2:0] read_state;
|
||||
reg [2:0] write_state;
|
||||
reg [6:0] sbuf;
|
||||
reg cmd55;
|
||||
reg [7:0] cmd;
|
||||
reg [2:0] bit_cnt;
|
||||
reg [3:0] byte_cnt;
|
||||
reg [7:0] reply;
|
||||
reg [7:0] reply0, reply1, reply2, reply3;
|
||||
reg [3:0] reply_len;
|
||||
reg tx_finish;
|
||||
reg rx_finish;
|
||||
reg old_sck;
|
||||
reg synced;
|
||||
reg [5:0] ack;
|
||||
reg io_ack;
|
||||
reg [4:0] idle_cnt = 0;
|
||||
reg [2:0] wait_m_cnt;
|
||||
reg [1:0] sd_buf, spi_buf;
|
||||
|
||||
reg [6:0] sbuf;
|
||||
reg [2:0] bit_cnt;
|
||||
|
||||
wire last_bit = &bit_cnt || OCTAL;
|
||||
wire [7:0] ibuf = OCTAL ? mosi : {sbuf,mosi[0]};
|
||||
|
||||
always @(posedge clk_spi) begin
|
||||
reg [2:0] read_state;
|
||||
reg [2:0] write_state;
|
||||
reg [1:0] pref_state;
|
||||
reg [5:0] cmd;
|
||||
reg cmd55;
|
||||
reg [39:0] reply;
|
||||
reg [3:0] byte_cnt;
|
||||
reg old_sck;
|
||||
reg [2:0] ack;
|
||||
reg [2:0] wait_m_cnt;
|
||||
reg [31:0] arg;
|
||||
|
||||
ack[1:0] <= {ack[0],sd_ack};
|
||||
if(ack[1] == ack[0]) ack[2] <= ack[1];
|
||||
|
||||
if(~ack[2] & ack[1]) {sd_rd,sd_wr} <= 0;
|
||||
if( ack[2] & ~ack[1]) begin
|
||||
sd_buf <= sd_buf + 1'd1;
|
||||
sd_lba <= sd_lba + 1;
|
||||
end
|
||||
|
||||
if(buffer_wr & ~&buffer_ptr) buffer_ptr <= buffer_ptr + 1'd1;
|
||||
buffer_wr <= 0;
|
||||
|
||||
ack <= {ack[4:0], sd_ack};
|
||||
if(ack[5:4] == 2'b10) io_ack <= 1;
|
||||
if(ack[5:4] == 2'b01) {sd_rd,sd_wr} <= 0;
|
||||
|
||||
old_sck <= sck;
|
||||
|
||||
if(~ss) idle_cnt <= 31;
|
||||
else if(~old_sck && sck && idle_cnt) idle_cnt <= idle_cnt - 1'd1;
|
||||
|
||||
if(reset || !idle_cnt) begin
|
||||
if(reset) begin
|
||||
bit_cnt <= 0;
|
||||
byte_cnt <= 15;
|
||||
synced <= 0;
|
||||
miso <= 1;
|
||||
sbuf <= 7'b1111111;
|
||||
tx_finish <= 0;
|
||||
rx_finish <= 0;
|
||||
byte_cnt <= '1;
|
||||
miso <= '1;
|
||||
cmd <= 0;
|
||||
sd_wr <= 0;
|
||||
sd_rd <= 0;
|
||||
read_state <= RD_STATE_IDLE;
|
||||
write_state <= WR_STATE_IDLE;
|
||||
pref_state <= PREF_STATE_IDLE;
|
||||
end
|
||||
else begin
|
||||
|
||||
if(old_sck & ~sck & ~ss) begin
|
||||
tx_finish <= 0;
|
||||
miso <= 1; // default: send 1's (busy/wait)
|
||||
|
||||
if(byte_cnt == 5+NCR) begin
|
||||
miso <= reply[~bit_cnt];
|
||||
|
||||
if(bit_cnt == 7) begin
|
||||
// these three commands all have a reply_len of 0 and will thus
|
||||
// not send more than a single reply byte
|
||||
|
||||
// CMD9: SEND_CSD
|
||||
// CMD10: SEND_CID
|
||||
if((cmd == 'h49) | (cmd == 'h4a))
|
||||
read_state <= RD_STATE_SEND_TOKEN; // jump directly to data transmission
|
||||
|
||||
// CMD17/CMD18
|
||||
if((cmd == 'h51) | (cmd == 'h52)) begin
|
||||
io_ack <= 0;
|
||||
read_state <= RD_STATE_WAIT_IO; // start waiting for data from io controller
|
||||
lba <= new_lba;
|
||||
sd_rd <= 1; // trigger request to io controller
|
||||
end
|
||||
if(buffer_wr) begin
|
||||
if(~&buffer_ptr) buffer_ptr <= buffer_ptr + 1'd1;
|
||||
else begin
|
||||
spi_buf <= spi_buf + 1'd1;
|
||||
sd_wr <= 1;
|
||||
end
|
||||
end
|
||||
else if((reply_len > 0) && (byte_cnt == 5+NCR+1)) miso <= reply0[~bit_cnt];
|
||||
else if((reply_len > 1) && (byte_cnt == 5+NCR+2)) miso <= reply1[~bit_cnt];
|
||||
else if((reply_len > 2) && (byte_cnt == 5+NCR+3)) miso <= reply2[~bit_cnt];
|
||||
else if((reply_len > 3) && (byte_cnt == 5+NCR+4)) miso <= reply3[~bit_cnt];
|
||||
else begin
|
||||
if(byte_cnt > 5+NCR && read_state==RD_STATE_IDLE && write_state==WR_STATE_IDLE) tx_finish <= 1;
|
||||
end
|
||||
|
||||
// ---------- read state machine processing -------------
|
||||
|
||||
case(read_state)
|
||||
RD_STATE_IDLE: ; // do nothing
|
||||
|
||||
|
||||
// waiting for io controller to return data
|
||||
RD_STATE_WAIT_IO: begin
|
||||
if(io_ack & (bit_cnt == 7)) read_state <= RD_STATE_SEND_TOKEN;
|
||||
end
|
||||
|
||||
// send data token
|
||||
RD_STATE_SEND_TOKEN: begin
|
||||
miso <= READ_DATA_TOKEN[~bit_cnt];
|
||||
|
||||
if(bit_cnt == 7) begin
|
||||
read_state <= RD_STATE_SEND_DATA; // next: send data
|
||||
buffer_ptr <= 0;
|
||||
if(cmd == 'h49) buffer_ptr <= 16;
|
||||
case(pref_state)
|
||||
PREF_STATE_IDLE:
|
||||
if(((sd_buf - spi_buf) <= 1) && (read_state != RD_STATE_IDLE) && (cmd == 17 || cmd == 18)) begin
|
||||
sd_rd <= 1;
|
||||
pref_state <= PREF_STATE_RD;
|
||||
end
|
||||
end
|
||||
|
||||
// send data
|
||||
RD_STATE_SEND_DATA: begin
|
||||
|
||||
miso <= ((cmd == 'h49) | (cmd == 'h4A)) ? config_dout[~bit_cnt] : buffer_dout[~bit_cnt];
|
||||
|
||||
if(bit_cnt == 7) begin
|
||||
|
||||
// sent 512 sector data bytes?
|
||||
if((cmd == 'h51) & &buffer_ptr) read_state <= RD_STATE_IDLE;
|
||||
else if((cmd == 'h52) & &buffer_ptr) begin
|
||||
read_state <= RD_STATE_WAIT_M;
|
||||
wait_m_cnt <= 0;
|
||||
end
|
||||
|
||||
// sent 16 cid/csd data bytes?
|
||||
else if(((cmd == 'h49) | (cmd == 'h4a)) & (&buffer_ptr[3:0])) read_state <= RD_STATE_IDLE;
|
||||
|
||||
// not done yet -> trigger read of next data byte
|
||||
else buffer_ptr <= buffer_ptr + 1'd1;
|
||||
PREF_STATE_RD:
|
||||
if(read_state == RD_STATE_IDLE) begin
|
||||
pref_state <= PREF_STATE_IDLE;
|
||||
end
|
||||
end
|
||||
|
||||
RD_STATE_WAIT_M: begin
|
||||
if(bit_cnt == 7) begin
|
||||
wait_m_cnt <= wait_m_cnt + 1'd1;
|
||||
if(&wait_m_cnt) begin
|
||||
lba <= lba + 1;
|
||||
io_ack <= 0;
|
||||
sd_rd <= 1;
|
||||
read_state <= RD_STATE_WAIT_IO;
|
||||
end
|
||||
else if(ack[2] & ~ack[1]) begin
|
||||
pref_state <= (cmd == 18) ? PREF_STATE_IDLE : PREF_STATE_FINISH;
|
||||
end
|
||||
|
||||
PREF_STATE_FINISH:
|
||||
if(read_state == RD_STATE_IDLE) begin
|
||||
pref_state <= PREF_STATE_IDLE;
|
||||
end
|
||||
end
|
||||
endcase
|
||||
|
||||
// ------------------ write support ----------------------
|
||||
// send write data response
|
||||
if(write_state == WR_STATE_SEND_DRESP) miso <= WRITE_DATA_RESPONSE[~bit_cnt];
|
||||
|
||||
// busy after write until the io controller sends ack
|
||||
if(write_state == WR_STATE_BUSY) miso <= 0;
|
||||
end
|
||||
|
||||
if(~old_sck & sck & ~ss) begin
|
||||
|
||||
if(synced) bit_cnt <= bit_cnt + 1'd1;
|
||||
|
||||
// assemble byte
|
||||
if(bit_cnt != 7) begin
|
||||
sbuf[6:0] <= { sbuf[5:0], mosi };
|
||||
|
||||
// resync while waiting for token
|
||||
if(write_state==WR_STATE_EXP_DTOKEN) begin
|
||||
if(cmd == 'h58) begin
|
||||
if({sbuf,mosi} == 8'hfe) begin
|
||||
write_state <= WR_STATE_RECV_DATA;
|
||||
buffer_ptr <= 0;
|
||||
bit_cnt <= 0;
|
||||
end
|
||||
end
|
||||
else begin
|
||||
if({sbuf,mosi} == 8'hfc) begin
|
||||
write_state <= WR_STATE_RECV_DATA;
|
||||
buffer_ptr <= 0;
|
||||
bit_cnt <= 0;
|
||||
end
|
||||
if({sbuf,mosi} == 8'hfd) begin
|
||||
write_state <= WR_STATE_IDLE;
|
||||
rx_finish <= 1;
|
||||
bit_cnt <= 0;
|
||||
end
|
||||
end
|
||||
end
|
||||
old_sck <= sck;
|
||||
if(ss) begin
|
||||
bit_cnt <= 0;
|
||||
byte_cnt <= '1;
|
||||
miso <= '1;
|
||||
end
|
||||
else begin
|
||||
// finished reading one byte
|
||||
// byte counter runs against 15 byte boundary
|
||||
if(byte_cnt != 15) byte_cnt <= byte_cnt + 1'd1;
|
||||
else if(old_sck & ~sck) begin
|
||||
miso <= '1; // default: send 1's (busy/wait)
|
||||
if(byte_cnt >= NCR) {miso,reply} <= {reply, {SZ{1'b1}}};
|
||||
|
||||
// byte_cnt > 6 -> complete command received
|
||||
// first byte of valid command is 01xxxxxx
|
||||
// don't accept new commands once a write or read command has been accepted
|
||||
if((byte_cnt > 5) & (write_state == WR_STATE_IDLE) & (read_state == RD_STATE_IDLE) && !rx_finish) begin
|
||||
byte_cnt <= 0;
|
||||
cmd <= { sbuf, mosi};
|
||||
// ---------- read state machine processing -------------
|
||||
case(read_state)
|
||||
RD_STATE_IDLE: ;
|
||||
|
||||
// set cmd55 flag if previous command was 55
|
||||
cmd55 <= (cmd == 'h77);
|
||||
end
|
||||
RD_STATE_START: begin
|
||||
if(byte_cnt == NCR && last_bit) read_state <= (cmd == 9 || cmd == 10) ? RD_STATE_SEND_TOKEN : RD_STATE_WAIT_IO;
|
||||
end
|
||||
|
||||
if((byte_cnt > 5) & (read_state == RD_STATE_WAIT_M) && ({sbuf, mosi} == 8'h4c)) begin
|
||||
byte_cnt <= 0;
|
||||
rx_finish <= 0;
|
||||
cmd <= {sbuf, mosi};
|
||||
read_state <= RD_STATE_IDLE;
|
||||
end
|
||||
// waiting for io controller to return data
|
||||
RD_STATE_WAIT_IO: begin
|
||||
if(sd_buf != spi_buf && last_bit) read_state <= RD_STATE_SEND_TOKEN;
|
||||
end
|
||||
|
||||
// parse additional command bytes
|
||||
if(byte_cnt == 0) new_lba[31:24] <= { sbuf, mosi};
|
||||
if(byte_cnt == 1) new_lba[23:16] <= { sbuf, mosi};
|
||||
if(byte_cnt == 2) new_lba[15:8] <= { sbuf, mosi};
|
||||
if(byte_cnt == 3) new_lba[7:0] <= { sbuf, mosi};
|
||||
|
||||
// last byte (crc) received, evaluate
|
||||