mirror of
https://github.com/Gehstock/Mist_FPGA.git
synced 2026-01-19 09:18:02 +00:00
Moon Patrol: update to common MiST components
This commit is contained in:
parent
30bf24c2dd
commit
6402124f90
@ -155,7 +155,7 @@ set_global_assignment -name GENERATE_RBF_FILE ON
|
||||
# SignalTap II Assignments
|
||||
# ========================
|
||||
set_global_assignment -name ENABLE_SIGNALTAP OFF
|
||||
set_global_assignment -name USE_SIGNALTAP_FILE stp1.stp
|
||||
set_global_assignment -name USE_SIGNALTAP_FILE Output/snd.stp
|
||||
|
||||
# Advanced I/O Timing Assignments
|
||||
# ===============================
|
||||
@ -187,7 +187,7 @@ set_global_assignment -name CYCLONEIII_CONFIGURATION_SCHEME "PASSIVE SERIAL"
|
||||
set_global_assignment -name FORCE_CONFIGURATION_VCCIO ON
|
||||
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "NO HEAT SINK WITH STILL AIR"
|
||||
set_global_assignment -name POWER_BOARD_THERMAL_MODEL "NONE (CONSERVATIVE)"
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
set_global_assignment -name QIP_FILE ../../../common/mist/mist.qip
|
||||
set_global_assignment -name VHDL_FILE src/bitmapctl_e.vhd
|
||||
set_global_assignment -name VHDL_FILE src/tilemapctl_e.vhd
|
||||
set_global_assignment -name VHDL_FILE src/target_pkg.vhd
|
||||
@ -232,10 +232,7 @@ set_global_assignment -name VHDL_FILE src/bitmap2_ctl.vhd
|
||||
set_global_assignment -name VHDL_FILE src/bitmap1_ctl.vhd
|
||||
set_global_assignment -name VHDL_FILE src/i82c55.vhd
|
||||
set_global_assignment -name VERILOG_FILE src/keyboard.v
|
||||
set_global_assignment -name VERILOG_FILE src/scandoubler.v
|
||||
set_global_assignment -name SYSTEMVERILOG_FILE src/rgb2ypbpr.sv
|
||||
set_global_assignment -name VERILOG_FILE src/osd.v
|
||||
set_global_assignment -name VERILOG_FILE src/user_io.v
|
||||
set_global_assignment -name VHDL_FILE src/sprite_array.vhd
|
||||
set_global_assignment -name VHDL_FILE src/Clock.vhd
|
||||
set_global_assignment -name VHDL_FILE src/build_id.vhd
|
||||
set_global_assignment -name VHDL_FILE src/build_id.vhd
|
||||
set_instance_assignment -name PARTITION_HIERARCHY root_partition -to | -section_id Top
|
||||
@ -8,6 +8,7 @@ use work.pace_pkg.all;
|
||||
use work.video_controller_pkg.all;
|
||||
|
||||
use work.build_id.all;
|
||||
use work.mist.all;
|
||||
|
||||
entity mpatrol is
|
||||
port
|
||||
@ -50,8 +51,8 @@ architecture SYN of mpatrol is
|
||||
--MIST
|
||||
signal audio : std_logic;
|
||||
signal status : std_logic_vector(31 downto 0);
|
||||
signal joystick1 : std_logic_vector(7 downto 0);
|
||||
signal joystick2 : std_logic_vector(7 downto 0);
|
||||
signal joystick1 : std_logic_vector(31 downto 0);
|
||||
signal joystick2 : std_logic_vector(31 downto 0);
|
||||
signal joystick : std_logic_vector(7 downto 0);
|
||||
signal kbd_joy : std_logic_vector(9 downto 0);
|
||||
signal switches : std_logic_vector(1 downto 0);
|
||||
@ -64,24 +65,6 @@ architecture SYN of mpatrol is
|
||||
signal audio_out : std_logic_vector(11 downto 0);
|
||||
signal sound_data : std_logic_vector(7 downto 0);
|
||||
|
||||
signal sd_r : std_logic_vector(5 downto 0);
|
||||
signal sd_g : std_logic_vector(5 downto 0);
|
||||
signal sd_b : std_logic_vector(5 downto 0);
|
||||
signal sd_hs : std_logic;
|
||||
signal sd_vs : std_logic;
|
||||
|
||||
signal osd_red_i : std_logic_vector(5 downto 0);
|
||||
signal osd_green_i : std_logic_vector(5 downto 0);
|
||||
signal osd_blue_i : std_logic_vector(5 downto 0);
|
||||
signal osd_vs_i : std_logic;
|
||||
signal osd_hs_i : std_logic;
|
||||
signal osd_red_o : std_logic_vector(5 downto 0);
|
||||
signal osd_green_o : std_logic_vector(5 downto 0);
|
||||
signal osd_blue_o : std_logic_vector(5 downto 0);
|
||||
signal vga_y_o : std_logic_vector(5 downto 0);
|
||||
signal vga_pb_o : std_logic_vector(5 downto 0);
|
||||
signal vga_pr_o : std_logic_vector(5 downto 0);
|
||||
|
||||
constant CONF_STR : string :=
|
||||
"MPATROL;;"&
|
||||
"O12,Scandoubler Fx,None,CRT 25%,CRT 50%,CRT 75%;"&
|
||||
@ -118,77 +101,6 @@ component keyboard
|
||||
joystick :out STD_LOGIC_VECTOR(9 downto 0));
|
||||
end component;
|
||||
|
||||
component user_io
|
||||
generic ( STRLEN : integer := 0 );
|
||||
port (
|
||||
clk_sys : in STD_LOGIC;
|
||||
conf_str : in std_logic_vector(8*STRLEN-1 downto 0);
|
||||
SPI_CLK : in STD_LOGIC;
|
||||
SPI_SS_IO : in STD_LOGIC;
|
||||
SPI_MOSI : in STD_LOGIC;
|
||||
SPI_MISO : out STD_LOGIC;
|
||||
switches : out STD_LOGIC_VECTOR(1 downto 0);
|
||||
buttons : out STD_LOGIC_VECTOR(1 downto 0);
|
||||
scandoubler_disable : out STD_LOGIC;
|
||||
ypbpr : out STD_LOGIC;
|
||||
joystick_1 : out STD_LOGIC_VECTOR(7 downto 0);
|
||||
joystick_0 : out STD_LOGIC_VECTOR(7 downto 0);
|
||||
status : out STD_LOGIC_VECTOR(31 downto 0);
|
||||
ps2_kbd_clk : out STD_LOGIC;
|
||||
ps2_kbd_data : out STD_LOGIC);
|
||||
end component;
|
||||
|
||||
component scandoubler
|
||||
port (
|
||||
clk_sys : in std_logic;
|
||||
scanlines : in std_logic_vector(1 downto 0);
|
||||
|
||||
hs_in : in std_logic;
|
||||
vs_in : in std_logic;
|
||||
r_in : in std_logic_vector(5 downto 0);
|
||||
g_in : in std_logic_vector(5 downto 0);
|
||||
b_in : in std_logic_vector(5 downto 0);
|
||||
|
||||
hs_out : out std_logic;
|
||||
vs_out : out std_logic;
|
||||
r_out : out std_logic_vector(5 downto 0);
|
||||
g_out : out std_logic_vector(5 downto 0);
|
||||
b_out : out std_logic_vector(5 downto 0)
|
||||
);
|
||||
end component scandoubler;
|
||||
|
||||
component osd
|
||||
generic ( OSD_COLOR : integer := 1 ); -- blue
|
||||
port (
|
||||
clk_sys : in std_logic;
|
||||
|
||||
R_in : in std_logic_vector(5 downto 0);
|
||||
G_in : in std_logic_vector(5 downto 0);
|
||||
B_in : in std_logic_vector(5 downto 0);
|
||||
HSync : in std_logic;
|
||||
VSync : in std_logic;
|
||||
|
||||
R_out : out std_logic_vector(5 downto 0);
|
||||
G_out : out std_logic_vector(5 downto 0);
|
||||
B_out : out std_logic_vector(5 downto 0);
|
||||
|
||||
SPI_SCK : in std_logic;
|
||||
SPI_SS3 : in std_logic;
|
||||
SPI_DI : in std_logic
|
||||
);
|
||||
end component osd;
|
||||
|
||||
COMPONENT rgb2ypbpr
|
||||
PORT (
|
||||
red : IN std_logic_vector(5 DOWNTO 0);
|
||||
green : IN std_logic_vector(5 DOWNTO 0);
|
||||
blue : IN std_logic_vector(5 DOWNTO 0);
|
||||
y : OUT std_logic_vector(5 DOWNTO 0);
|
||||
pb : OUT std_logic_vector(5 DOWNTO 0);
|
||||
pr : OUT std_logic_vector(5 DOWNTO 0)
|
||||
);
|
||||
END COMPONENT;
|
||||
|
||||
begin
|
||||
|
||||
--CLOCK
|
||||
@ -279,7 +191,7 @@ u_keyboard : keyboard
|
||||
joystick => kbd_joy
|
||||
);
|
||||
|
||||
joystick <= joystick1 or joystick2;
|
||||
joystick <= joystick1(7 downto 0) or joystick2(7 downto 0);
|
||||
|
||||
inputs_i.jamma_n.coin(1) <= not (joystick(6) or kbd_joy(3));--ESC
|
||||
inputs_i.jamma_n.p(1).start <= not (kbd_joy(1) or joystick1(7));--KB 1
|
||||
@ -352,64 +264,29 @@ pace_inst : entity work.pace
|
||||
sound_data_o => sound_data
|
||||
);
|
||||
|
||||
scandoubler_inst: scandoubler
|
||||
mist_video: work.mist.mist_video
|
||||
port map (
|
||||
clk_sys => clk_vid,
|
||||
scanlines => status(2 downto 1),
|
||||
|
||||
hs_in => video_o.hsync,
|
||||
vs_in => video_o.vsync,
|
||||
r_in => video_o.rgb.r(9 downto 4),
|
||||
g_in => video_o.rgb.g(9 downto 4),
|
||||
b_in => video_o.rgb.b(9 downto 4),
|
||||
|
||||
hs_out => sd_hs,
|
||||
vs_out => sd_vs,
|
||||
r_out => sd_r,
|
||||
g_out => sd_g,
|
||||
b_out => sd_b
|
||||
);
|
||||
|
||||
osd_inst: osd
|
||||
port map (
|
||||
clk_sys => clk_vid,
|
||||
scandoubler_disable => scandoubler_disable,
|
||||
ypbpr => ypbpr,
|
||||
rotate => "00",
|
||||
|
||||
SPI_SCK => SPI_SCK,
|
||||
SPI_SS3 => SPI_SS3,
|
||||
SPI_DI => SPI_DI,
|
||||
|
||||
R_in => osd_red_i,
|
||||
G_in => osd_green_i,
|
||||
B_in => osd_blue_i,
|
||||
HSync => osd_hs_i,
|
||||
VSync => osd_vs_i,
|
||||
HSync => video_o.hsync,
|
||||
VSync => video_o.vsync,
|
||||
R => video_o.rgb.r(9 downto 4),
|
||||
G => video_o.rgb.g(9 downto 4),
|
||||
B => video_o.rgb.b(9 downto 4),
|
||||
|
||||
R_out => osd_red_o,
|
||||
G_out => osd_green_o,
|
||||
B_out => osd_blue_o
|
||||
VGA_HS => VGA_HS,
|
||||
VGA_VS => VGA_VS,
|
||||
VGA_R => VGA_R,
|
||||
VGA_G => VGA_G,
|
||||
VGA_B => VGA_B
|
||||
);
|
||||
|
||||
rgb2component: component rgb2ypbpr
|
||||
port map (
|
||||
red => osd_red_o,
|
||||
green => osd_green_o,
|
||||
blue => osd_blue_o,
|
||||
y => vga_y_o,
|
||||
pb => vga_pb_o,
|
||||
pr => vga_pr_o
|
||||
);
|
||||
|
||||
osd_red_i <= video_o.rgb.r(9 downto 4) when scandoubler_disable = '1' else sd_r;
|
||||
osd_green_i <= video_o.rgb.g(9 downto 4) when scandoubler_disable = '1' else sd_g;
|
||||
osd_blue_i <= video_o.rgb.b(9 downto 4) when scandoubler_disable = '1' else sd_b;
|
||||
osd_hs_i <= video_o.hsync when scandoubler_disable = '1' else sd_hs;
|
||||
osd_vs_i <= video_o.vsync when scandoubler_disable = '1' else sd_vs;
|
||||
|
||||
-- If 15kHz Video - composite sync to VGA_HS and VGA_VS high for MiST RGB cable
|
||||
VGA_HS <= not (video_o.hsync xor video_o.vsync) when scandoubler_disable='1' else not (sd_hs xor sd_vs) when ypbpr='1' else sd_hs;
|
||||
VGA_VS <= '1' when scandoubler_disable='1' or ypbpr='1' else sd_vs;
|
||||
VGA_R <= vga_pr_o when ypbpr='1' else osd_red_o;
|
||||
VGA_G <= vga_y_o when ypbpr='1' else osd_green_o;
|
||||
VGA_B <= vga_pb_o when ypbpr='1' else osd_blue_o;
|
||||
--
|
||||
end SYN;
|
||||
|
||||
@ -1,179 +0,0 @@
|
||||
// A simple OSD implementation. Can be hooked up between a cores
|
||||
// VGA output and the physical VGA pins
|
||||
|
||||
module osd (
|
||||
// OSDs pixel clock, should be synchronous to cores pixel clock to
|
||||
// avoid jitter.
|
||||
input clk_sys,
|
||||
|
||||
// SPI interface
|
||||
input SPI_SCK,
|
||||
input SPI_SS3,
|
||||
input SPI_DI,
|
||||
|
||||
// VGA signals coming from core
|
||||
input [5:0] R_in,
|
||||
input [5:0] G_in,
|
||||
input [5:0] B_in,
|
||||
input HSync,
|
||||
input VSync,
|
||||
|
||||
// VGA signals going to video connector
|
||||
output [5:0] R_out,
|
||||
output [5:0] G_out,
|
||||
output [5:0] B_out
|
||||
);
|
||||
|
||||
parameter OSD_X_OFFSET = 10'd0;
|
||||
parameter OSD_Y_OFFSET = 10'd0;
|
||||
parameter OSD_COLOR = 3'd0;
|
||||
|
||||
localparam OSD_WIDTH = 10'd256;
|
||||
localparam OSD_HEIGHT = 10'd128;
|
||||
|
||||
// *********************************************************************************
|
||||
// spi client
|
||||
// *********************************************************************************
|
||||
|
||||
// this core supports only the display related OSD commands
|
||||
// of the minimig
|
||||
reg osd_enable;
|
||||
(* ramstyle = "no_rw_check" *) reg [7:0] osd_buffer[2047:0]; // the OSD buffer itself
|
||||
|
||||
// the OSD has its own SPI interface to the io controller
|
||||
always@(posedge SPI_SCK, posedge SPI_SS3) begin
|
||||
reg [4:0] cnt;
|
||||
reg [10:0] bcnt;
|
||||
reg [7:0] sbuf;
|
||||
reg [7:0] cmd;
|
||||
|
||||
if(SPI_SS3) begin
|
||||
cnt <= 0;
|
||||
bcnt <= 0;
|
||||
end else begin
|
||||
sbuf <= {sbuf[6:0], SPI_DI};
|
||||
|
||||
// 0:7 is command, rest payload
|
||||
if(cnt < 15) cnt <= cnt + 1'd1;
|
||||
else cnt <= 8;
|
||||
|
||||
if(cnt == 7) begin
|
||||
cmd <= {sbuf[6:0], SPI_DI};
|
||||
|
||||
// lower three command bits are line address
|
||||
bcnt <= {sbuf[1:0], SPI_DI, 8'h00};
|
||||
|
||||
// command 0x40: OSDCMDENABLE, OSDCMDDISABLE
|
||||
if(sbuf[6:3] == 4'b0100) osd_enable <= SPI_DI;
|
||||
end
|
||||
|
||||
// command 0x20: OSDCMDWRITE
|
||||
if((cmd[7:3] == 5'b00100) && (cnt == 15)) begin
|
||||
osd_buffer[bcnt] <= {sbuf[6:0], SPI_DI};
|
||||
bcnt <= bcnt + 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// *********************************************************************************
|
||||
// video timing and sync polarity anaylsis
|
||||
// *********************************************************************************
|
||||
|
||||
// horizontal counter
|
||||
reg [9:0] h_cnt;
|
||||
reg [9:0] hs_low, hs_high;
|
||||
wire hs_pol = hs_high < hs_low;
|
||||
wire [9:0] dsp_width = hs_pol ? hs_low : hs_high;
|
||||
|
||||
// vertical counter
|
||||
reg [9:0] v_cnt;
|
||||
reg [9:0] vs_low, vs_high;
|
||||
wire vs_pol = vs_high < vs_low;
|
||||
wire [9:0] dsp_height = vs_pol ? vs_low : vs_high;
|
||||
|
||||
wire doublescan = (dsp_height>350);
|
||||
|
||||
reg ce_pix;
|
||||
always @(negedge clk_sys) begin
|
||||
integer cnt = 0;
|
||||
integer pixsz, pixcnt;
|
||||
reg hs;
|
||||
|
||||
cnt <= cnt + 1;
|
||||
hs <= HSync;
|
||||
|
||||
pixcnt <= pixcnt + 1;
|
||||
if(pixcnt == pixsz) pixcnt <= 0;
|
||||
ce_pix <= !pixcnt;
|
||||
|
||||
if(hs && ~HSync) begin
|
||||
cnt <= 0;
|
||||
pixsz <= (cnt >> 9) - 1;
|
||||
pixcnt <= 0;
|
||||
ce_pix <= 1;
|
||||
end
|
||||
end
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
reg hsD, hsD2;
|
||||
reg vsD, vsD2;
|
||||
|
||||
if(ce_pix) begin
|
||||
// bring hsync into local clock domain
|
||||
hsD <= HSync;
|
||||
hsD2 <= hsD;
|
||||
|
||||
// falling edge of HSync
|
||||
if(!hsD && hsD2) begin
|
||||
h_cnt <= 0;
|
||||
hs_high <= h_cnt;
|
||||
end
|
||||
|
||||
// rising edge of HSync
|
||||
else if(hsD && !hsD2) begin
|
||||
h_cnt <= 0;
|
||||
hs_low <= h_cnt;
|
||||
v_cnt <= v_cnt + 1'd1;
|
||||
end else begin
|
||||
h_cnt <= h_cnt + 1'd1;
|
||||
end
|
||||
|
||||
vsD <= VSync;
|
||||
vsD2 <= vsD;
|
||||
|
||||
// falling edge of VSync
|
||||
if(!vsD && vsD2) begin
|
||||
v_cnt <= 0;
|
||||
vs_high <= v_cnt;
|
||||
end
|
||||
|
||||
// rising edge of VSync
|
||||
else if(vsD && !vsD2) begin
|
||||
v_cnt <= 0;
|
||||
vs_low <= v_cnt;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// area in which OSD is being displayed
|
||||
wire [9:0] h_osd_start = ((dsp_width - OSD_WIDTH)>> 1) + OSD_X_OFFSET;
|
||||
wire [9:0] h_osd_end = h_osd_start + OSD_WIDTH;
|
||||
wire [9:0] v_osd_start = ((dsp_height- (OSD_HEIGHT<<doublescan))>> 1) + OSD_Y_OFFSET;
|
||||
wire [9:0] v_osd_end = v_osd_start + (OSD_HEIGHT<<doublescan);
|
||||
wire [9:0] osd_hcnt = h_cnt - h_osd_start + 1'd1; // one pixel offset for osd_byte register
|
||||
wire [9:0] osd_vcnt = v_cnt - v_osd_start;
|
||||
|
||||
wire osd_de = osd_enable &&
|
||||
(HSync != hs_pol) && (h_cnt >= h_osd_start) && (h_cnt < h_osd_end) &&
|
||||
(VSync != vs_pol) && (v_cnt >= v_osd_start) && (v_cnt < v_osd_end);
|
||||
|
||||
reg [7:0] osd_byte;
|
||||
always @(posedge clk_sys) if(ce_pix) osd_byte <= osd_buffer[{doublescan ? osd_vcnt[7:5] : osd_vcnt[6:4], osd_hcnt[7:0]}];
|
||||
|
||||
wire osd_pixel = osd_byte[doublescan ? osd_vcnt[4:2] : osd_vcnt[3:1]];
|
||||
|
||||
assign R_out = !osd_de ? R_in : {osd_pixel, osd_pixel, OSD_COLOR[2], R_in[5:3]};
|
||||
assign G_out = !osd_de ? G_in : {osd_pixel, osd_pixel, OSD_COLOR[1], G_in[5:3]};
|
||||
assign B_out = !osd_de ? B_in : {osd_pixel, osd_pixel, OSD_COLOR[0], B_in[5:3]};
|
||||
|
||||
endmodule
|
||||
@ -1,55 +0,0 @@
|
||||
module rgb2ypbpr (
|
||||
input [5:0] red,
|
||||
input [5:0] green,
|
||||
input [5:0] blue,
|
||||
|
||||
output [5:0] y,
|
||||
output [5:0] pb,
|
||||
output [5:0] pr
|
||||
);
|
||||
|
||||
wire [5:0] yuv_full[225] = '{
|
||||
6'd0, 6'd0, 6'd0, 6'd0, 6'd1, 6'd1, 6'd1, 6'd1,
|
||||
6'd2, 6'd2, 6'd2, 6'd3, 6'd3, 6'd3, 6'd3, 6'd4,
|
||||
6'd4, 6'd4, 6'd5, 6'd5, 6'd5, 6'd5, 6'd6, 6'd6,
|
||||
6'd6, 6'd7, 6'd7, 6'd7, 6'd7, 6'd8, 6'd8, 6'd8,
|
||||
6'd9, 6'd9, 6'd9, 6'd9, 6'd10, 6'd10, 6'd10, 6'd11,
|
||||
6'd11, 6'd11, 6'd11, 6'd12, 6'd12, 6'd12, 6'd13, 6'd13,
|
||||
6'd13, 6'd13, 6'd14, 6'd14, 6'd14, 6'd15, 6'd15, 6'd15,
|
||||
6'd15, 6'd16, 6'd16, 6'd16, 6'd17, 6'd17, 6'd17, 6'd17,
|
||||
6'd18, 6'd18, 6'd18, 6'd19, 6'd19, 6'd19, 6'd19, 6'd20,
|
||||
6'd20, 6'd20, 6'd21, 6'd21, 6'd21, 6'd21, 6'd22, 6'd22,
|
||||
6'd22, 6'd23, 6'd23, 6'd23, 6'd23, 6'd24, 6'd24, 6'd24,
|
||||
6'd25, 6'd25, 6'd25, 6'd25, 6'd26, 6'd26, 6'd26, 6'd27,
|
||||
6'd27, 6'd27, 6'd27, 6'd28, 6'd28, 6'd28, 6'd29, 6'd29,
|
||||
6'd29, 6'd29, 6'd30, 6'd30, 6'd30, 6'd31, 6'd31, 6'd31,
|
||||
6'd31, 6'd32, 6'd32, 6'd32, 6'd33, 6'd33, 6'd33, 6'd33,
|
||||
6'd34, 6'd34, 6'd34, 6'd35, 6'd35, 6'd35, 6'd35, 6'd36,
|
||||
6'd36, 6'd36, 6'd36, 6'd37, 6'd37, 6'd37, 6'd38, 6'd38,
|
||||
6'd38, 6'd38, 6'd39, 6'd39, 6'd39, 6'd40, 6'd40, 6'd40,
|
||||
6'd40, 6'd41, 6'd41, 6'd41, 6'd42, 6'd42, 6'd42, 6'd42,
|
||||
6'd43, 6'd43, 6'd43, 6'd44, 6'd44, 6'd44, 6'd44, 6'd45,
|
||||
6'd45, 6'd45, 6'd46, 6'd46, 6'd46, 6'd46, 6'd47, 6'd47,
|
||||
6'd47, 6'd48, 6'd48, 6'd48, 6'd48, 6'd49, 6'd49, 6'd49,
|
||||
6'd50, 6'd50, 6'd50, 6'd50, 6'd51, 6'd51, 6'd51, 6'd52,
|
||||
6'd52, 6'd52, 6'd52, 6'd53, 6'd53, 6'd53, 6'd54, 6'd54,
|
||||
6'd54, 6'd54, 6'd55, 6'd55, 6'd55, 6'd56, 6'd56, 6'd56,
|
||||
6'd56, 6'd57, 6'd57, 6'd57, 6'd58, 6'd58, 6'd58, 6'd58,
|
||||
6'd59, 6'd59, 6'd59, 6'd60, 6'd60, 6'd60, 6'd60, 6'd61,
|
||||
6'd61, 6'd61, 6'd62, 6'd62, 6'd62, 6'd62, 6'd63, 6'd63,
|
||||
6'd63
|
||||
};
|
||||
|
||||
wire [18:0] y_8 = 19'd04096 + ({red, 8'd0} + {red, 3'd0}) + ({green, 9'd0} + {green, 2'd0}) + ({blue, 6'd0} + {blue, 5'd0} + {blue, 2'd0});
|
||||
wire [18:0] pb_8 = 19'd32768 - ({red, 7'd0} + {red, 4'd0} + {red, 3'd0}) - ({green, 8'd0} + {green, 5'd0} + {green, 3'd0}) + ({blue, 8'd0} + {blue, 7'd0} + {blue, 6'd0});
|
||||
wire [18:0] pr_8 = 19'd32768 + ({red, 8'd0} + {red, 7'd0} + {red, 6'd0}) - ({green, 8'd0} + {green, 6'd0} + {green, 5'd0} + {green, 4'd0} + {green, 3'd0}) - ({blue, 6'd0} + {blue , 3'd0});
|
||||
|
||||
wire [7:0] y_i = ( y_8[17:8] < 16) ? 8'd16 : ( y_8[17:8] > 235) ? 8'd235 : y_8[15:8];
|
||||
wire [7:0] pb_i = (pb_8[17:8] < 16) ? 8'd16 : (pb_8[17:8] > 240) ? 8'd240 : pb_8[15:8];
|
||||
wire [7:0] pr_i = (pr_8[17:8] < 16) ? 8'd16 : (pr_8[17:8] > 240) ? 8'd240 : pr_8[15:8];
|
||||
|
||||
assign pr = yuv_full[pr_i - 8'd16];
|
||||
assign y = yuv_full[y_i - 8'd16];
|
||||
assign pb = yuv_full[pb_i - 8'd16];
|
||||
|
||||
endmodule
|
||||
@ -1,178 +0,0 @@
|
||||
//
|
||||
// scandoubler.v
|
||||
//
|
||||
// Copyright (c) 2015 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
// TODO: Delay vsync one line
|
||||
|
||||
module scandoubler
|
||||
(
|
||||
// system interface
|
||||
input clk_sys,
|
||||
|
||||
// scanlines (00-none 01-25% 10-50% 11-75%)
|
||||
input [1:0] scanlines,
|
||||
|
||||
// shifter video interface
|
||||
input hs_in,
|
||||
input vs_in,
|
||||
input [5:0] r_in,
|
||||
input [5:0] g_in,
|
||||
input [5:0] b_in,
|
||||
|
||||
// output interface
|
||||
output reg hs_out,
|
||||
output reg vs_out,
|
||||
output reg [5:0] r_out,
|
||||
output reg [5:0] g_out,
|
||||
output reg [5:0] b_out
|
||||
);
|
||||
|
||||
// try to detect changes in input signal and lock input clock gate
|
||||
// it
|
||||
|
||||
reg [1:0] i_div;
|
||||
wire ce_x1 = (i_div == 2'b01);
|
||||
wire ce_x2 = i_div[0];
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
reg last_hs_in;
|
||||
last_hs_in <= hs_in;
|
||||
if(last_hs_in & !hs_in) begin
|
||||
i_div <= 2'b00;
|
||||
end else begin
|
||||
i_div <= i_div + 2'd1;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// --------------------- create output signals -----------------
|
||||
// latch everything once more to make it glitch free and apply scanline effect
|
||||
reg scanline;
|
||||
always @(posedge clk_sys) begin
|
||||
if(ce_x2) begin
|
||||
hs_out <= hs_sd;
|
||||
vs_out <= vs_in;
|
||||
|
||||
// reset scanlines at every new screen
|
||||
if(vs_out != vs_in) scanline <= 0;
|
||||
|
||||
// toggle scanlines at begin of every hsync
|
||||
if(hs_out && !hs_sd) scanline <= !scanline;
|
||||
|
||||
// if no scanlines or not a scanline
|
||||
if(!scanline || !scanlines) begin
|
||||
r_out <= sd_out[17:12];
|
||||
g_out <= sd_out[11:6];
|
||||
b_out <= sd_out[5:0];
|
||||
end else begin
|
||||
case(scanlines)
|
||||
1: begin // reduce 25% = 1/2 + 1/4
|
||||
r_out <= {1'b0, sd_out[17:14], 1'b0} + {2'b00, sd_out[17:14]};
|
||||
g_out <= {1'b0, sd_out[11:8], 1'b0} + {2'b00, sd_out[11:8] };
|
||||
b_out <= {1'b0, sd_out[5:2], 1'b0} + {2'b00, sd_out[5:2] };
|
||||
end
|
||||
|
||||
2: begin // reduce 50% = 1/2
|
||||
r_out <= {1'b0, sd_out[17:14], 1'b0};
|
||||
g_out <= {1'b0, sd_out[11:8], 1'b0};
|
||||
b_out <= {1'b0, sd_out[5:2], 1'b0};
|
||||
end
|
||||
|
||||
3: begin // reduce 75% = 1/4
|
||||
r_out <= {2'b00, sd_out[17:14]};
|
||||
g_out <= {2'b00, sd_out[11:8]};
|
||||
b_out <= {2'b00, sd_out[5:2]};
|
||||
end
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// scan doubler output register
|
||||
reg [17:0] sd_out;
|
||||
|
||||
// ==================================================================
|
||||
// ======================== the line buffers ========================
|
||||
// ==================================================================
|
||||
|
||||
// 2 lines of 512 pixels 3*6 bit RGB
|
||||
(* ramstyle = "no_rw_check" *) reg [17:0] sd_buffer[2048];
|
||||
|
||||
// use alternating sd_buffers when storing/reading data
|
||||
reg line_toggle;
|
||||
|
||||
// total hsync time (in 16MHz cycles), hs_total reaches 1024
|
||||
reg [9:0] hs_max;
|
||||
reg [9:0] hs_rise;
|
||||
reg [9:0] hcnt;
|
||||
|
||||
always @(posedge clk_sys) begin
|
||||
reg hsD, vsD;
|
||||
|
||||
if(ce_x1) begin
|
||||
hsD <= hs_in;
|
||||
|
||||
// falling edge of hsync indicates start of line
|
||||
if(hsD && !hs_in) begin
|
||||
hs_max <= hcnt;
|
||||
hcnt <= 0;
|
||||
end else begin
|
||||
hcnt <= hcnt + 1'd1;
|
||||
end
|
||||
|
||||
// save position of rising edge
|
||||
if(!hsD && hs_in) hs_rise <= hcnt;
|
||||
|
||||
vsD <= vs_in;
|
||||
if(vsD != vs_in) line_toggle <= 0;
|
||||
|
||||
// begin of incoming hsync
|
||||
if(hsD && !hs_in) line_toggle <= !line_toggle;
|
||||
|
||||
sd_buffer[{line_toggle, hcnt}] <= {r_in, g_in, b_in};
|
||||
end
|
||||
end
|
||||
|
||||
// ==================================================================
|
||||
// ==================== output timing generation ====================
|
||||
// ==================================================================
|
||||
|
||||
reg [9:0] sd_hcnt;
|
||||
reg hs_sd;
|
||||
|
||||
// timing generation runs 32 MHz (twice the input signal analysis speed)
|
||||
always @(posedge clk_sys) begin
|
||||
reg hsD;
|
||||
|
||||
if(ce_x2) begin
|
||||
hsD <= hs_in;
|
||||
|
||||
// output counter synchronous to input and at twice the rate
|
||||
sd_hcnt <= sd_hcnt + 1'd1;
|
||||
if(hsD && !hs_in) sd_hcnt <= hs_max;
|
||||
if(sd_hcnt == hs_max) sd_hcnt <= 0;
|
||||
|
||||
// replicate horizontal sync at twice the speed
|
||||
if(sd_hcnt == hs_max) hs_sd <= 0;
|
||||
if(sd_hcnt == hs_rise) hs_sd <= 1;
|
||||
|
||||
// read data from line sd_buffer
|
||||
sd_out <= sd_buffer[{~line_toggle, sd_hcnt}];
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@ -1,550 +0,0 @@
|
||||
//
|
||||
// user_io.v
|
||||
//
|
||||
// user_io for the MiST board
|
||||
// http://code.google.com/p/mist-board/
|
||||
//
|
||||
// Copyright (c) 2014 Till Harbaum <till@harbaum.org>
|
||||
//
|
||||
// This source file is free software: you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License as published
|
||||
// by the Free Software Foundation, either version 3 of the License, or
|
||||
// (at your option) any later version.
|
||||
//
|
||||
// This source file is distributed in the hope that it will be useful,
|
||||
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
// GNU General Public License for more details.
|
||||
//
|
||||
// You should have received a copy of the GNU General Public License
|
||||
// along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
//
|
||||
|
||||
// parameter STRLEN and the actual length of conf_str have to match
|
||||
|
||||
module user_io #(parameter STRLEN=0, parameter PS2DIV=100) (
|
||||
input [(8*STRLEN)-1:0] conf_str,
|
||||
|
||||
input clk_sys, // clock for system-related messages (kbd, joy, etc...)
|
||||
input clk_sd, // clock for SD-card related messages
|
||||
|
||||
input SPI_CLK,
|
||||
input SPI_SS_IO,
|
||||
output reg SPI_MISO,
|
||||
input SPI_MOSI,
|
||||
|
||||
output reg [31:0] joystick_0,
|
||||
output reg [31:0] joystick_1,
|
||||
output reg [31:0] joystick_2,
|
||||
output reg [31:0] joystick_3,
|
||||
output reg [31:0] joystick_4,
|
||||
output reg [15:0] joystick_analog_0,
|
||||
output reg [15:0] joystick_analog_1,
|
||||
output [1:0] buttons,
|
||||
output [1:0] switches,
|
||||
output scandoubler_disable,
|
||||
output ypbpr,
|
||||
output reg [31:0] status,
|
||||
|
||||
// connection to sd card emulation
|
||||
input [31:0] sd_lba,
|
||||
input sd_rd,
|
||||
input sd_wr,
|
||||
output reg sd_ack,
|
||||
output reg sd_ack_conf,
|
||||
input sd_conf,
|
||||
input sd_sdhc,
|
||||
output reg [7:0] sd_dout, // valid on rising edge of sd_dout_strobe
|
||||
output reg sd_dout_strobe,
|
||||
input [7:0] sd_din,
|
||||
output reg sd_din_strobe,
|
||||
output reg [8:0] sd_buff_addr,
|
||||
|
||||
output reg img_mounted, //rising edge if a new image is mounted
|
||||
output reg [31:0] img_size, // size of image in bytes
|
||||
|
||||
// ps2 keyboard/mouse emulation
|
||||
output ps2_kbd_clk,
|
||||
output reg ps2_kbd_data,
|
||||
output ps2_mouse_clk,
|
||||
output reg ps2_mouse_data,
|
||||
|
||||
// mouse data
|
||||
output reg [8:0] mouse_x,
|
||||
output reg [8:0] mouse_y,
|
||||
output reg [7:0] mouse_flags, // YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn
|
||||
output reg mouse_strobe, // mouse data is valid on mouse_strobe
|
||||
|
||||
// serial com port
|
||||
input [7:0] serial_data,
|
||||
input serial_strobe
|
||||
);
|
||||
|
||||
reg [6:0] sbuf;
|
||||
reg [7:0] cmd;
|
||||
reg [2:0] bit_cnt; // counts bits 0-7 0-7 ...
|
||||
reg [9:0] byte_cnt; // counts bytes
|
||||
reg [7:0] but_sw;
|
||||
reg [2:0] stick_idx;
|
||||
|
||||
assign buttons = but_sw[1:0];
|
||||
assign switches = but_sw[3:2];
|
||||
assign scandoubler_disable = but_sw[4];
|
||||
assign ypbpr = but_sw[5];
|
||||
|
||||
// this variant of user_io is for 8 bit cores (type == a4) only
|
||||
wire [7:0] core_type = 8'ha4;
|
||||
|
||||
// command byte read by the io controller
|
||||
wire [7:0] sd_cmd = { 4'h5, sd_conf, sd_sdhc, sd_wr, sd_rd };
|
||||
|
||||
wire spi_sck = SPI_CLK;
|
||||
|
||||
// ---------------- PS2 ---------------------
|
||||
// 8 byte fifos to store ps2 bytes
|
||||
localparam PS2_FIFO_BITS = 3;
|
||||
|
||||
reg ps2_clk;
|
||||
always @(negedge clk_sys) begin
|
||||
integer cnt;
|
||||
cnt <= cnt + 1'd1;
|
||||
if(cnt == PS2DIV) begin
|
||||
ps2_clk <= ~ps2_clk;
|
||||
cnt <= 0;
|
||||
end
|
||||
end
|
||||
|
||||
// keyboard
|
||||
reg [7:0] ps2_kbd_fifo [(2**PS2_FIFO_BITS)-1:0];
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_kbd_wptr;
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_kbd_rptr;
|
||||
|
||||
// ps2 transmitter state machine
|
||||
reg [3:0] ps2_kbd_tx_state;
|
||||
reg [7:0] ps2_kbd_tx_byte;
|
||||
reg ps2_kbd_parity;
|
||||
|
||||
assign ps2_kbd_clk = ps2_clk || (ps2_kbd_tx_state == 0);
|
||||
|
||||
// ps2 transmitter
|
||||
// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
|
||||
reg ps2_kbd_r_inc;
|
||||
always@(posedge clk_sys) begin
|
||||
reg ps2_clkD;
|
||||
|
||||
ps2_clkD <= ps2_clk;
|
||||
if (~ps2_clkD & ps2_clk) begin
|
||||
ps2_kbd_r_inc <= 1'b0;
|
||||
|
||||
if(ps2_kbd_r_inc)
|
||||
ps2_kbd_rptr <= ps2_kbd_rptr + 1'd1;
|
||||
|
||||
// transmitter is idle?
|
||||
if(ps2_kbd_tx_state == 0) begin
|
||||
// data in fifo present?
|
||||
if(ps2_kbd_wptr != ps2_kbd_rptr) begin
|
||||
// load tx register from fifo
|
||||
ps2_kbd_tx_byte <= ps2_kbd_fifo[ps2_kbd_rptr];
|
||||
ps2_kbd_r_inc <= 1'b1;
|
||||
|
||||
// reset parity
|
||||
ps2_kbd_parity <= 1'b1;
|
||||
|
||||
// start transmitter
|
||||
ps2_kbd_tx_state <= 4'd1;
|
||||
|
||||
// put start bit on data line
|
||||
ps2_kbd_data <= 1'b0; // start bit is 0
|
||||
end
|
||||
end else begin
|
||||
|
||||
// transmission of 8 data bits
|
||||
if((ps2_kbd_tx_state >= 1)&&(ps2_kbd_tx_state < 9)) begin
|
||||
ps2_kbd_data <= ps2_kbd_tx_byte[0]; // data bits
|
||||
ps2_kbd_tx_byte[6:0] <= ps2_kbd_tx_byte[7:1]; // shift down
|
||||
if(ps2_kbd_tx_byte[0])
|
||||
ps2_kbd_parity <= !ps2_kbd_parity;
|
||||
end
|
||||
|
||||
// transmission of parity
|
||||
if(ps2_kbd_tx_state == 9)
|
||||
ps2_kbd_data <= ps2_kbd_parity;
|
||||
|
||||
// transmission of stop bit
|
||||
if(ps2_kbd_tx_state == 10)
|
||||
ps2_kbd_data <= 1'b1; // stop bit is 1
|
||||
|
||||
// advance state machine
|
||||
if(ps2_kbd_tx_state < 11)
|
||||
ps2_kbd_tx_state <= ps2_kbd_tx_state + 4'd1;
|
||||
else
|
||||
ps2_kbd_tx_state <= 4'd0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// mouse
|
||||
reg [7:0] ps2_mouse_fifo [(2**PS2_FIFO_BITS)-1:0];
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_mouse_wptr;
|
||||
reg [PS2_FIFO_BITS-1:0] ps2_mouse_rptr;
|
||||
|
||||
// ps2 transmitter state machine
|
||||
reg [3:0] ps2_mouse_tx_state;
|
||||
reg [7:0] ps2_mouse_tx_byte;
|
||||
reg ps2_mouse_parity;
|
||||
|
||||
assign ps2_mouse_clk = ps2_clk || (ps2_mouse_tx_state == 0);
|
||||
|
||||
// ps2 transmitter
|
||||
// Takes a byte from the FIFO and sends it in a ps2 compliant serial format.
|
||||
reg ps2_mouse_r_inc;
|
||||
always@(posedge clk_sys) begin
|
||||
reg ps2_clkD;
|
||||
|
||||
ps2_clkD <= ps2_clk;
|
||||
if (~ps2_clkD & ps2_clk) begin
|
||||
ps2_mouse_r_inc <= 1'b0;
|
||||
|
||||
if(ps2_mouse_r_inc)
|
||||
ps2_mouse_rptr <= ps2_mouse_rptr + 1'd1;
|
||||
|
||||
// transmitter is idle?
|
||||
if(ps2_mouse_tx_state == 0) begin
|
||||
// data in fifo present?
|
||||
if(ps2_mouse_wptr != ps2_mouse_rptr) begin
|
||||
// load tx register from fifo
|
||||
ps2_mouse_tx_byte <= ps2_mouse_fifo[ps2_mouse_rptr];
|
||||
ps2_mouse_r_inc <= 1'b1;
|
||||
|
||||
// reset parity
|
||||
ps2_mouse_parity <= 1'b1;
|
||||
|
||||
// start transmitter
|
||||
ps2_mouse_tx_state <= 4'd1;
|
||||
|
||||
// put start bit on data line
|
||||
ps2_mouse_data <= 1'b0; // start bit is 0
|
||||
end
|
||||
end else begin
|
||||
|
||||
// transmission of 8 data bits
|
||||
if((ps2_mouse_tx_state >= 1)&&(ps2_mouse_tx_state < 9)) begin
|
||||
ps2_mouse_data <= ps2_mouse_tx_byte[0]; // data bits
|
||||
ps2_mouse_tx_byte[6:0] <= ps2_mouse_tx_byte[7:1]; // shift down
|
||||
if(ps2_mouse_tx_byte[0])
|
||||
ps2_mouse_parity <= !ps2_mouse_parity;
|
||||
end
|
||||
|
||||
// transmission of parity
|
||||
if(ps2_mouse_tx_state == 9)
|
||||
ps2_mouse_data <= ps2_mouse_parity;
|
||||
|
||||
// transmission of stop bit
|
||||
if(ps2_mouse_tx_state == 10)
|
||||
ps2_mouse_data <= 1'b1; // stop bit is 1
|
||||
|
||||
// advance state machine
|
||||
if(ps2_mouse_tx_state < 11)
|
||||
ps2_mouse_tx_state <= ps2_mouse_tx_state + 4'd1;
|
||||
else
|
||||
ps2_mouse_tx_state <= 4'd0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// fifo to receive serial data from core to be forwarded to io controller
|
||||
|
||||
// 16 byte fifo to store serial bytes
|
||||
localparam SERIAL_OUT_FIFO_BITS = 6;
|
||||
reg [7:0] serial_out_fifo [(2**SERIAL_OUT_FIFO_BITS)-1:0];
|
||||
reg [SERIAL_OUT_FIFO_BITS-1:0] serial_out_wptr;
|
||||
reg [SERIAL_OUT_FIFO_BITS-1:0] serial_out_rptr;
|
||||
|
||||
wire serial_out_data_available = serial_out_wptr != serial_out_rptr;
|
||||
wire [7:0] serial_out_byte = serial_out_fifo[serial_out_rptr] /* synthesis keep */;
|
||||
wire [7:0] serial_out_status = { 7'b1000000, serial_out_data_available};
|
||||
|
||||
// status[0] is reset signal from io controller and is thus used to flush
|
||||
// the fifo
|
||||
always @(posedge serial_strobe or posedge status[0]) begin
|
||||
if(status[0] == 1) begin
|
||||
serial_out_wptr <= 0;
|
||||
end else begin
|
||||
serial_out_fifo[serial_out_wptr] <= serial_data;
|
||||
serial_out_wptr <= serial_out_wptr + 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
always@(negedge spi_sck or posedge status[0]) begin
|
||||
if(status[0] == 1) begin
|
||||
serial_out_rptr <= 0;
|
||||
end else begin
|
||||
if((byte_cnt != 0) && (cmd == 8'h1b)) begin
|
||||
// read last bit -> advance read pointer
|
||||
if((bit_cnt == 7) && !byte_cnt[0] && serial_out_data_available)
|
||||
serial_out_rptr <= serial_out_rptr + 1'd1;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
// SPI bit and byte counters
|
||||
always@(posedge spi_sck or posedge SPI_SS_IO) begin
|
||||
if(SPI_SS_IO == 1) begin
|
||||
bit_cnt <= 0;
|
||||
byte_cnt <= 0;
|
||||
end else begin
|
||||
if((bit_cnt == 7)&&(~&byte_cnt))
|
||||
byte_cnt <= byte_cnt + 8'd1;
|
||||
|
||||
bit_cnt <= bit_cnt + 1'd1;
|
||||
end
|
||||
end
|
||||
|
||||
// SPI transmitter FPGA -> IO
|
||||
reg [7:0] spi_byte_out;
|
||||
|
||||
always@(negedge spi_sck or posedge SPI_SS_IO) begin
|
||||
if(SPI_SS_IO == 1) begin
|
||||
SPI_MISO <= 1'bZ;
|
||||
end else begin
|
||||
SPI_MISO <= spi_byte_out[~bit_cnt];
|
||||
end
|
||||
end
|
||||
|
||||
always@(posedge spi_sck or posedge SPI_SS_IO) begin
|
||||
reg [31:0] sd_lba_r;
|
||||
|
||||
if(SPI_SS_IO == 1) begin
|
||||
spi_byte_out <= core_type;
|
||||
end else begin
|
||||
// read the command byte to choose the response
|
||||
if(bit_cnt == 7) begin
|
||||
if(!byte_cnt) cmd <= {sbuf, SPI_MOSI};
|
||||
|
||||
spi_byte_out <= 0;
|
||||
case({(!byte_cnt) ? {sbuf, SPI_MOSI} : cmd})
|
||||
// reading config string
|
||||
8'h14: if(byte_cnt < STRLEN) spi_byte_out <= conf_str[(STRLEN - byte_cnt - 1)<<3 +:8];
|
||||
|
||||
// reading sd card status
|
||||
8'h16: if(byte_cnt == 0) begin
|
||||
spi_byte_out <= sd_cmd;
|
||||
sd_lba_r <= sd_lba;
|
||||
end
|
||||
else if(byte_cnt < 5) spi_byte_out <= sd_lba_r[(4-byte_cnt)<<3 +:8];
|
||||
|
||||
// reading sd card write data
|
||||
8'h18: spi_byte_out <= sd_din;
|
||||
8'h1b:
|
||||
// send alternating flag byte and data
|
||||
if(byte_cnt[0]) spi_byte_out <= serial_out_status;
|
||||
else spi_byte_out <= serial_out_byte;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// SPI receiver IO -> FPGA
|
||||
|
||||
reg spi_receiver_strobe_r = 0;
|
||||
reg spi_transfer_end_r = 1;
|
||||
reg [7:0] spi_byte_in;
|
||||
|
||||
// Read at spi_sck clock domain, assemble bytes for transferring to clk_sys
|
||||
always@(posedge spi_sck or posedge SPI_SS_IO) begin
|
||||
|
||||
if(SPI_SS_IO == 1) begin
|
||||
spi_transfer_end_r <= 1;
|
||||
end else begin
|
||||
spi_transfer_end_r <= 0;
|
||||
|
||||
if(bit_cnt != 7)
|
||||
sbuf[6:0] <= { sbuf[5:0], SPI_MOSI };
|
||||
|
||||
// finished reading a byte, prepare to transfer to clk_sys
|
||||
if(bit_cnt == 7) begin
|
||||
spi_byte_in <= { sbuf, SPI_MOSI};
|
||||
spi_receiver_strobe_r <= ~spi_receiver_strobe_r;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Process bytes from SPI at the clk_sys domain
|
||||
always @(posedge clk_sys) begin
|
||||
|
||||
reg spi_receiver_strobe;
|
||||
reg spi_transfer_end;
|
||||
reg spi_receiver_strobeD;
|
||||
reg spi_transfer_endD;
|
||||
reg [7:0] acmd;
|
||||
reg [7:0] abyte_cnt; // counts bytes
|
||||
|
||||
reg [7:0] mouse_flags_r;
|
||||
reg [7:0] mouse_x_r;
|
||||
|
||||
//synchronize between SPI and sys clock domains
|
||||
spi_receiver_strobeD <= spi_receiver_strobe_r;
|
||||
spi_receiver_strobe <= spi_receiver_strobeD;
|
||||
spi_transfer_endD <= spi_transfer_end_r;
|
||||
spi_transfer_end <= spi_transfer_endD;
|
||||
|
||||
mouse_strobe <= 0;
|
||||
|
||||
if (~spi_transfer_endD & spi_transfer_end) begin
|
||||
abyte_cnt <= 8'd0;
|
||||
end else if (spi_receiver_strobeD ^ spi_receiver_strobe) begin
|
||||
|
||||
if(~&abyte_cnt)
|
||||
abyte_cnt <= abyte_cnt + 8'd1;
|
||||
|
||||
if(abyte_cnt == 0) begin
|
||||
acmd <= spi_byte_in;
|
||||
end else begin
|
||||
case(acmd)
|
||||
// buttons and switches
|
||||
8'h01: but_sw <= spi_byte_in;
|
||||
8'h60: if (abyte_cnt < 5) joystick_0[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
|
||||
8'h61: if (abyte_cnt < 5) joystick_1[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
|
||||
8'h62: if (abyte_cnt < 5) joystick_2[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
|
||||
8'h63: if (abyte_cnt < 5) joystick_3[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
|
||||
8'h64: if (abyte_cnt < 5) joystick_4[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
|
||||
8'h04: begin
|
||||
// store incoming ps2 mouse bytes
|
||||
ps2_mouse_fifo[ps2_mouse_wptr] <= spi_byte_in;
|
||||
ps2_mouse_wptr <= ps2_mouse_wptr + 1'd1;
|
||||
if (abyte_cnt == 1) mouse_flags_r <= spi_byte_in;
|
||||
else if (abyte_cnt == 2) mouse_x_r <= spi_byte_in;
|
||||
else if (abyte_cnt == 3) begin
|
||||
// flags: YOvfl, XOvfl, dy8, dx8, 1, mbtn, rbtn, lbtn
|
||||
mouse_flags <= mouse_flags_r;
|
||||
mouse_x <= { mouse_flags_r[4], mouse_x_r };
|
||||
mouse_y <= { mouse_flags_r[5], spi_byte_in };
|
||||
mouse_strobe <= 1;
|
||||
end
|
||||
end
|
||||
8'h05: begin
|
||||
// store incoming ps2 keyboard bytes
|
||||
ps2_kbd_fifo[ps2_kbd_wptr] <= spi_byte_in;
|
||||
ps2_kbd_wptr <= ps2_kbd_wptr + 1'd1;
|
||||
end
|
||||
|
||||
// joystick analog
|
||||
8'h1a: begin
|
||||
// first byte is joystick index
|
||||
if(abyte_cnt == 1)
|
||||
stick_idx <= spi_byte_in[2:0];
|
||||
else if(abyte_cnt == 2) begin
|
||||
// second byte is x axis
|
||||
if(stick_idx == 0)
|
||||
joystick_analog_0[15:8] <= spi_byte_in;
|
||||
else if(stick_idx == 1)
|
||||
joystick_analog_1[15:8] <= spi_byte_in;
|
||||
end else if(abyte_cnt == 3) begin
|
||||
// third byte is y axis
|
||||
if(stick_idx == 0)
|
||||
joystick_analog_0[7:0] <= spi_byte_in;
|
||||
else if(stick_idx == 1)
|
||||
joystick_analog_1[7:0] <= spi_byte_in;
|
||||
end
|
||||
end
|
||||
|
||||
8'h15: status <= spi_byte_in;
|
||||
|
||||
// status, 32bit version
|
||||
8'h1e: if(abyte_cnt<5) status[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
|
||||
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
// Process SD-card related bytes from SPI at the clk_sd domain
|
||||
always @(posedge clk_sd) begin
|
||||
|
||||
reg spi_receiver_strobe;
|
||||
reg spi_transfer_end;
|
||||
reg spi_receiver_strobeD;
|
||||
reg spi_transfer_endD;
|
||||
reg sd_wrD;
|
||||
reg [7:0] acmd;
|
||||
reg [7:0] abyte_cnt; // counts bytes
|
||||
|
||||
//synchronize between SPI and sd clock domains
|
||||
spi_receiver_strobeD <= spi_receiver_strobe_r;
|
||||
spi_receiver_strobe <= spi_receiver_strobeD;
|
||||
spi_transfer_endD <= spi_transfer_end_r;
|
||||
spi_transfer_end <= spi_transfer_endD;
|
||||
|
||||
if(sd_dout_strobe) begin
|
||||
sd_dout_strobe<= 0;
|
||||
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
|
||||
end
|
||||
|
||||
sd_din_strobe<= 0;
|
||||
sd_wrD <= sd_wr;
|
||||
// fetch the first byte immediately after the write command seen
|
||||
if (~sd_wrD & sd_wr) begin
|
||||
sd_buff_addr <= 0;
|
||||
sd_din_strobe <= 1;
|
||||
end
|
||||
|
||||
img_mounted <= 0;
|
||||
|
||||
if (~spi_transfer_endD & spi_transfer_end) begin
|
||||
abyte_cnt <= 8'd0;
|
||||
sd_ack <= 1'b0;
|
||||
sd_ack_conf <= 1'b0;
|
||||
sd_dout_strobe <= 1'b0;
|
||||
sd_din_strobe <= 1'b0;
|
||||
sd_buff_addr <= 0;
|
||||
end else if (spi_receiver_strobeD ^ spi_receiver_strobe) begin
|
||||
|
||||
if(~&abyte_cnt)
|
||||
abyte_cnt <= abyte_cnt + 8'd1;
|
||||
|
||||
if(abyte_cnt == 0) begin
|
||||
acmd <= spi_byte_in;
|
||||
|
||||
if(spi_byte_in == 8'h18) begin
|
||||
sd_din_strobe <= 1'b1;
|
||||
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
|
||||
end
|
||||
|
||||
if((spi_byte_in == 8'h17) || (spi_byte_in == 8'h18))
|
||||
sd_ack <= 1'b1;
|
||||
|
||||
end else begin
|
||||
case(acmd)
|
||||
|
||||
// send sector IO -> FPGA
|
||||
8'h17: begin
|
||||
// flag that download begins
|
||||
sd_dout_strobe <= 1'b1;
|
||||
sd_dout <= spi_byte_in;
|
||||
end
|
||||
|
||||
// send sector FPGA -> IO
|
||||
8'h18: begin
|
||||
sd_din_strobe <= 1'b1;
|
||||
if(~&sd_buff_addr) sd_buff_addr <= sd_buff_addr + 1'b1;
|
||||
end
|
||||
|
||||
// send SD config IO -> FPGA
|
||||
8'h19: begin
|
||||
// flag that download begins
|
||||
sd_dout_strobe <= 1'b1;
|
||||
sd_ack_conf <= 1'b1;
|
||||
sd_dout <= spi_byte_in;
|
||||
end
|
||||
|
||||
8'h1c: img_mounted <= 1;
|
||||
|
||||
// send image info
|
||||
8'h1d: if(abyte_cnt<5) img_size[(abyte_cnt-1)<<3 +:8] <= spi_byte_in;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
Loading…
x
Reference in New Issue
Block a user