📄 mctrl.vhd
字号:
regsd := (others => '-');
end if;
when "1000" =>
if WPROTEN then
regsd := wpr.wprot2.enable & wpr.wprot2.ablock &
wpr.wprot2.addr & wpr.wprot2.mask;
else
regsd := (others => '-');
end if;
when others => regsd := (others => '-');
end case;
if (r.read and r.ready2) = '1' then
v.rstate := idle;
elsif r.read = '0' then
v.rstate := rwrite;
v.ready := '1';
if (r.address(5 downto 2) = "0110") and (peo.irl = "0000") then
v.pwd := '1';
end if;
end if;
when rwrite =>
v.rstate := idle;
case r.address(5 downto 2) is
when "0000" =>
v.mcfg1.romrws := r.writedata(3 downto 0);
v.mcfg1.romwws := r.writedata(7 downto 4);
v.mcfg1.romwidth := r.writedata(9 downto 8);
v.mcfg1.romedac := r.writedata(10);
v.mcfg1.romwrite := r.writedata(11);
v.mcfg1.romleadin := r.writedata(12);
v.mcfg1.romleadout := r.writedata(13);
v.mcfg1.rombanksz := r.writedata(17 downto 14);
v.mcfg1.extlatch := r.writedata(18);
v.mcfg1.ioen := r.writedata(19);
v.mcfg1.iows := r.writedata(23 downto 20);
v.mcfg1.ioleadin := r.writedata(24);
v.mcfg1.ioleadout := r.writedata(25);
v.mcfg1.iordy := r.writedata(26);
v.mcfg1.iowidth := r.writedata(28 downto 27);
when "0001" =>
v.mcfg2.ramrws := r.writedata(1 downto 0);
v.mcfg2.ramwws := r.writedata(3 downto 2);
v.mcfg2.ramwidth := r.writedata(5 downto 4);
v.mcfg2.ramedac := r.writedata(6);
v.mcfg2.ramleadin := r.writedata(7);
v.mcfg2.ramleadout := r.writedata(8);
v.mcfg2.rambanksz := r.writedata(12 downto 9);
when "0010" =>
v.edacctrl.wcheckbits := r.writedata(6 downto 0);
v.edacctrl.wbypass := r.writedata(7);
when "0011" => v.failaddr := r.writedata;
when "0100" =>
v.memstat.lock := r.writedata(10);
v.memstat.mulerr := r.writedata(9);
v.memstat.newerr := r.writedata(8);
v.memstat.read := r.writedata(7);
v.memstat.asi := r.writedata(6 downto 3);
v.memstat.errtype := r.writedata(2 downto 0);
when "0101" =>
v.cctrl.ib := r.writedata(16);
v.cctrl.ite := r.writedata(13 downto 12);
v.cctrl.ide := r.writedata(11 downto 10);
v.cctrl.dte := r.writedata(9 downto 8);
v.cctrl.dde := r.writedata(7 downto 6);
v.cctrl.dfrz := r.writedata(5);
v.cctrl.ifrz := r.writedata(4);
v.cctrl.dcs := r.writedata(3 downto 2);
v.cctrl.ics := r.writedata(1 downto 0);
when "0111" =>
wprot1.enable := r.writedata(31);
wprot1.ablock := r.writedata(30);
wprot1.addr := r.writedata(29 downto 15);
wprot1.mask := r.writedata(14 downto 0);
when "1000" =>
wprot2.enable := r.writedata(31);
wprot2.ablock := r.writedata(30);
wprot2.addr := r.writedata(29 downto 15);
wprot2.mask := r.writedata(14 downto 0);
when others => null;
end case;
when eregs =>
v.regen := '1'; regsd := pbo.data;
if r.read = '1' then
if r.ready2 = '1' then
v.rstate := idle; v.regen := '0';
end if;
else
v.rstate := ewrite; v.ready := '1';
end if;
when ewrite =>
v.rstate := idle;
end case;
-- select appropriate data during reads
case r.area is
when rom | ram =>
if r.checkedac = '1' then dataout := edata.data;
else
if busw(1) = '1' then dataout := r.data;
else dataout := r.readdata(23 downto 0) & r.data(31 downto 24); end if;
end if;
when io => dataout := r.data;
when regs => dataout := regsd;
when others => dataout := (others => '-');
end case;
-- Merge (corrected) data during byte write
if r.checkedac = '1' then memdata := edata.data;
elsif busw(1) = '0' then memdata := r.readdata(23 downto 0) & r.data(31 downto 24);
else memdata := r.data; end if;
case r.busstate is
when bw2 => -- write back the merged word
case r.ba is
when "00" =>
v.writedata(15 downto 0) := memdata(15 downto 0);
if r.size(0) = '0' then
v.writedata(23 downto 16) := memdata(23 downto 16);
end if;
when "01" =>
v.writedata(31 downto 24) := memdata(31 downto 24);
v.writedata(15 downto 0) := memdata(15 downto 0);
when "10" =>
v.writedata(31 downto 16) := memdata(31 downto 16);
if r.size(0) = '0' then
v.writedata(7 downto 0) := memdata(7 downto 0);
end if;
when others =>
v.writedata(31 downto 8) := memdata(31 downto 8);
end case;
when others => null;
end case;
-- update memory status and failing address register if an error occured
failaddr := (others => '-');
merror := edata.merror and r.checkedac2;
cerror := edata.error and r.checkedac2;
bexc := r.ready and (not r.bexcn);
if (merror or r.mexc or cerror or bexc) = '1' then
failaddr := r.address2;
if r.mexc = '1' then
failaddr := r.address;
if r.werr = '1' then merrtype := ERR_WP;
else merrtype := ERR_ILLA; end if;
elsif bexc = '1' then
merrtype := ERR_BEXC; v.werr := not r.read;
elsif merror = '1' then
merrtype := ERR_UEDAC;
if (r.busstate = bw2) then v.werr := '1'; end if;
else
merrtype := ERR_CEDAC; v.cerror := '1';
end if;
if r.memstat.lock = '0' then
v.memstat.read := r.read; v.memstat.asi := r.asi;
v.memstat.errtype := merrtype; v.failaddr := failaddr;
v.memstat.lock := merror or r.mexc;
end if;
v.memstat.newerr := '1'; v.memstat.mulerr := r.memstat.newerr;
end if;
-- load checkbits into edac test cotrol register during edac test reads
if (r.master = data) and
((r.read and r.edacctrl.wbypass and r.checkedac2) = '1') then
if busw = "00" then
v.edacctrl.wcheckbits := r.data(30 downto 24);
else
v.edacctrl.wcheckbits := r.cb;
end if;
end if;
-- generate appropriate data ready and error signals
case v.master is
when inst => v.iready := v.ready;
when data => v.dready := v.ready and not v.pwd;
when dma => v.mready := v.ready and DMAEN;
when others => null;
end case;
case r.master is
when inst => imerror := merror;
when data => dmerror := (merror and r.read) or r.werr;
when dma => mmerror := ((merror and r.read) or r.werr) and DMAEN;
when others => null;
end case;
v.imexc := r.iready and r.mexc;
v.dmexc := (r.dready and (r.mexc or not r.bexcn) and r.read) or
((not r.bexcn) and (not r.read) and v.dready);
v.mmexc := ((r.mready and (r.mexc or not r.bexcn) and r.read) or
((not r.bexcn) and (not r.read) and v.mready)) and DMAEN;
-- release iu if irl /= 0
if (r.pwd = '1') and peo.irl /= "0000" then
v.dready := not r.dready;
end if;
-- delay release of r.pwd one clock
if r.dready = '1' then v.pwd := '0'; end if;
-- suppress ready signal and EDAC error during byte writes (data access only)
case r.busstate is
when bw1 | bw2 => v.dready := v.werr; dmerror := '0';
when others => null;
end case;
if v.busstate = bw1 then v.dready := '0'; end if;
-- generate chip select and output enable
rams := decode(adec);
v.ramsn := "1111";
v.ramoen := "1111";
v.iosn := '1';
romsn := '1';
v.oen := '1';
bwidth := "00";
if csen = '1' then
case v.area is
when rom =>
romsn := v.mexc; v.oen := v.mexc or not v.read;
bwidth := r.mcfg1.romwidth;
when ram =>
bwidth := r.mcfg2.ramwidth;
if v.mexc = '0' then
v.ramsn := not rams;
if (v.read = '1') then v.ramoen := v.ramsn; end if;
end if;
when io =>
v.iosn := '0'; v.oen := not v.read; bwidth := r.mcfg1.iowidth;
when others => null;
end case;
end if;
v.romsn(0) := romsn or v.address(28);
v.romsn(1) := romsn or not v.address(28);
case bwidth is
when "00" => v.bdrive := "000" & bdrive;
when "01" => v.bdrive := "00" & bdrive & bdrive;
when others => v.bdrive := (others => bdrive);
end case;
-- generate appropriate write strobe
if r.wren = '1' then
wrn <= r.ramsn; writen <= r.romsn(0) and r.romsn(1) and r.iosn;
else
wrn <= "1111"; writen <= '1';
end if;
-- generate memory address
if RAWADDR and (r.mcfg1.extlatch = '1') then
memo.address <= v.address(27 downto 0);
else
memo.address <= r.address(27 downto 0);
end if;
-- use d(15:0) as input ports (only usefull in 8-bit mode)
pbi.pioh <= r.data(15 downto 0);
-- reset
if rst = '0' then
v.bstate := idle; v.busstate := idle; v.rstate := idle;
v.master := inst; v.read := '1'; v.ajam := '0'; v.pwd := '0';
v.memstat.lock := '0';
v.memstat.mulerr := '0';
v.memstat.newerr := '0';
v.mcfg1.romrws := "1111";
v.mcfg1.romwws := "1111";
v.mcfg1.romwidth := mctrli.romwidth;
v.mcfg1.romedac := mctrli.romedac;
v.mcfg1.romwrite := '0';
v.mcfg1.romleadin := '1';
v.mcfg1.romleadout := '1';
v.mcfg1.rombanksz := "0000";
v.mcfg1.extlatch := '0';
v.mcfg1.ioen := '0';
v.cctrl.ib := '0';
v.cctrl.dcs := "00";
v.cctrl.ics := "00";
v.edacctrl.wbypass := '0';
wprot1.enable := '0';
wprot2.enable := '0';
end if;
-- drive various register inputs and external outputs
ri <= v;
wpv.wprot1 <= wprot1;
wpv.wprot2 <= wprot2;
pbi.read <= mcdi.read;
mctrlo.cerror <= r.cerror;
mcio.data <= dataout;
mcio.ics <= r.cctrl.ics;
mcio.burst <= r.cctrl.ib;
mcio.mexc <= r.imexc or imerror;
mcio.ready <= r.iready;
mcdo.data <= dataout;
mcdo.dcs <= r.cctrl.dcs;
mcdo.mexc <= r.dmexc or dmerror;
mcdo.ready <= r.dready;
mcmo.data <= dataout;
mcmo.mexc <= r.mmexc or mmerror;
mcmo.ready <= r.mready;
memo.ramsn <= r.ramsn;
memo.ramoen <= r.ramoen;
memo.romsn <= r.romsn;
memo.oen <= r.oen;
memo.iosn <= r.iosn;
memo.read <= r.read;
memo.bdrive <= r.bdrive;
memo.data <= r.writedata;
memo.checkbits <= cbout;
pbi.address <= r.address(7 downto 2);
pbi.data <= r.writedata;
pbi.enable <= r.regen;
end process;
fregs : process(clk)
begin
if clk'event and (clk = '0') then
memo.wrn <= wrn;
memo.writen <= writen;
end if;
end process;
stdregs : process(clk)
begin
if clk'event and (clk = '1') then
r <= ri;
end if;
end process;
wpreggen : if WPROTEN generate
wpregs : process(clk)
begin
if clk'event and (clk = '1') then
wpr <= wpv;
end if;
end process;
end generate;
end;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -