From e8c3cca1cdbdccff542bc7eaf63b4be93420e0e7 Mon Sep 17 00:00:00 2001 From: harbaum Date: Tue, 23 Apr 2013 19:23:31 +0000 Subject: [PATCH] Dirty bus error fix --- cores/mist/TG68KdotC_Kernel.vhd | 68 ++++++++++++++++++++++----------- cores/mist/mist_top.v | 18 ++++++--- cores/mist/video.v | 28 +++++++++----- 3 files changed, 76 insertions(+), 38 deletions(-) diff --git a/cores/mist/TG68KdotC_Kernel.vhd b/cores/mist/TG68KdotC_Kernel.vhd index 7a13652..d518a29 100644 --- a/cores/mist/TG68KdotC_Kernel.vhd +++ b/cores/mist/TG68KdotC_Kernel.vhd @@ -19,6 +19,8 @@ -- -- ------------------------------------------------------------------------------ ------------------------------------------------------------------------------ +-- add berr handling 10.03.2013 + -- bugfix session 07/08.Feb.2013 -- movem ,-(an) -- movem (an)+, - thanks Gerhard Suttner @@ -76,7 +78,7 @@ entity TG68KdotC_Kernel is data_in : in std_logic_vector(15 downto 0); IPL : in std_logic_vector(2 downto 0):="111"; IPL_autovector : in std_logic:='0'; - berr : in std_logic:='0'; --TH + berr : in std_logic:='0'; -- only 68000 Stackpointer dummy CPU : in std_logic_vector(1 downto 0):="00"; -- 00->68000 01->68010 11->68020(only some parts - yet) addr : buffer std_logic_vector(31 downto 0); data_write : out std_logic_vector(15 downto 0); @@ -207,7 +209,7 @@ architecture logic of TG68KdotC_Kernel is signal set_V_Flag : bit; signal set_vectoraddr : bit; signal writeSR : bit; - signal trap_berr : bit; -- TH + signal trap_berr : bit; signal trap_illegal : bit; signal trap_addr_error : bit; signal trap_priv : bit; @@ -221,6 +223,7 @@ architecture logic of TG68KdotC_Kernel is signal trapd : bit; signal trap_SR : std_logic_vector(7 downto 0); signal make_trace : std_logic; + signal make_berr : std_logic; signal set_stop : bit; signal stop : bit; @@ -726,7 +729,8 @@ PROCESS (clk, setdisp, memaddr_a, briefdata, memaddr_delta, setdispbyte, datatyp IF rising_edge(clk) THEN IF clkena_lw='1' THEN trap_vector(31 downto 8) <= (others => '0'); - IF trap_berr='1' THEN +-- IF trap_addr_fault='1' THEN + IF trap_berr='1' THEN trap_vector(7 downto 0) <= X"08"; END IF; IF trap_addr_error='1' THEN @@ -844,7 +848,7 @@ PROCESS (clk, setdisp, memaddr_a, briefdata, memaddr_delta, setdispbyte, datatyp ----------------------------------------------------------------------------- -- PC Calc + fetch opcode ----------------------------------------------------------------------------- -PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro_state, stop, make_trace, IPL_nr, FlagsSR, set_rot_cnt, opcode, writePCbig, set_exec, exec, +PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro_state, stop, make_trace, make_berr, IPL_nr, FlagsSR, set_rot_cnt, opcode, writePCbig, set_exec, exec, PC_dataa, PC_datab, setnextpass, last_data_read, TG68_PC_brw, TG68_PC_word, Z_error, trap_trap, trap_trapv, interrupt, tmp_TG68_PC, TG68_PC) BEGIN @@ -889,7 +893,8 @@ PROCESS (clk, IPL, setstate, state, exec_write_back, set_direct_data, next_micro setinterrupt <= '0'; IF setstate="00" AND next_micro_state=idle AND setnextpass='0' AND (exec_write_back='0' OR state="11") AND set_rot_cnt="000001" AND set_exec(opcCHK)='0'THEN setendOPC <= '1'; - IF FlagsSR(2 downto 0)'0'); set_exec <= (OTHERS=>'0'); set(update_ld) <= '0'; @@ -1313,6 +1328,13 @@ PROCESS (clk, cpu, OP1out, OP2out, opcode, exe_condition, nextpass, micro_state, END IF; setstate <= "01"; END IF; + IF interrupt='1' AND trap_berr='1' THEN + next_micro_state <= trap0; + IF preSVmode='0' THEN + set(changeMode) <= '1'; + END IF; + setstate <= "01"; + END IF; IF micro_state=int1 OR (interrupt='1' AND trap_trace='1') THEN next_micro_state <= trap0; -- IF cpu(0)='0' THEN @@ -2847,7 +2869,7 @@ PROCESS (clk, cpu, OP1out, OP2out, opcode, exe_condition, nextpass, micro_state, -- set_datatype <= "10"; next_micro_state <= trap1; ELSE - IF trap_interrupt='1' OR trap_trace='1' THEN + IF trap_interrupt='1' OR trap_trace='1' OR trap_berr='1' THEN writePC <= '1'; END IF; datatype <= "10"; @@ -2868,19 +2890,19 @@ PROCESS (clk, cpu, OP1out, OP2out, opcode, exe_condition, nextpass, micro_state, setstate <= "11"; datatype <= "01"; writeSR <= '1'; --- IF trap_berr='1' THEN -- TH - IF trap_vector = X"08" THEN -- TH + IF trap_berr='1' THEN next_micro_state <= trap4; - ELSE - next_micro_state <= trap3; - END IF; + ELSE + next_micro_state <= trap3; + END IF; WHEN trap3 => -- TRAP set_vectoraddr <= '1'; datatype <= "10"; set(direct_delta) <= '1'; set(directPC) <= '1'; - setstate <= "10"; - next_micro_state <= nopnop; + setstate <= "10"; + next_micro_state <= nopnop; + WHEN trap4 => -- TRAP set(presub) <= '1'; setstackaddr <='1'; diff --git a/cores/mist/mist_top.v b/cores/mist/mist_top.v index 1a2d593..a349c0d 100644 --- a/cores/mist/mist_top.v +++ b/cores/mist/mist_top.v @@ -64,12 +64,15 @@ wire tg68_berr = (dtack_timeout == 5'd31); // || cpu_write_illegal; // certain bus error reg [3:0] berr_cnt_out; reg [3:0] berr_cnt; +reg berrD; always @(posedge clk_8) begin + berrD <= tg68_berr; + if(reset) begin berr_cnt <= 4'd0; end else begin berr_cnt_out <= 4'd0; - if(tg68_berr) begin + if(tg68_berr && !berrD) begin berr_cnt_out <= berr_cnt + 4'd1; berr_cnt <= berr_cnt + 4'd1; end @@ -94,10 +97,15 @@ always @(posedge clk_8) begin end else begin // timeout only when cpu owns the bus and when // neither dtack nor fast ram are active - if(!tg68_dtack || br || tg68_cpuena) - dtack_timeout <= 5'd0; - else if(dtack_timeout != 5'd31) - dtack_timeout <= dtack_timeout + 5'd1; + if(dtack_timeout != 5'd31) begin + if(!tg68_dtack || br || tg68_cpuena) + dtack_timeout <= 5'd0; + else + dtack_timeout <= dtack_timeout + 5'd1; + end else + // leave bus error when next instruction is read + if(!tg68_dtack && (tg68_cpustate[1:0] == 2'd3)) + dtack_timeout <= 1'b0; end end diff --git a/cores/mist/video.v b/cores/mist/video.v index 66cbf74..865887b 100644 --- a/cores/mist/video.v +++ b/cores/mist/video.v @@ -42,11 +42,11 @@ module video ( output reg [15:0] reg_dout, // screen interface - output hs, // H_SYNC - output vs, // V_SYNC - output [5:0] video_r, // Red[5:0] - output [5:0] video_g, // Green[5:0] - output [5:0] video_b, // Blue[5:0] + output reg hs, // H_SYNC + output reg vs, // V_SYNC + output reg [5:0] video_r, // Red[5:0] + output reg [5:0] video_g, // Green[5:0] + output reg [5:0] video_b, // Blue[5:0] // system config input pal56, // use VGA compatible 56hz for PAL @@ -162,11 +162,14 @@ wire [9:0] vcnt = mono?vcnt_mono:vcnt_color; wire bd = mono?1'b0:bd_color; // monochome is 640x480 (hs & vs neg) // color is 800x600 (hs & vs pos) -assign hs = mono?~hs_mono:hs_color; -assign vs = mono?~vs_mono:vs_color; wire hmax = mono?hmax_mono:hmax_color; wire vmax = mono?vmax_mono:vmax_color; +always @(posedge clk) begin + hs <= mono?~hs_mono:hs_color; + vs <= mono?~vs_mono:vs_color; +end + reg [15:0] tx, tx0, tx1, tx2, tx3; // output shift registers localparam BASE_ADDR = 23'h8000; // default video base address 0x010000 @@ -290,10 +293,15 @@ wire [2:0] stvid_g = mono?mono_rgb:color_g; wire [2:0] stvid_b = mono?mono_rgb:color_b; // ... add OSD overlay and feed into VGA outputs -assign video_r = !osd_oe?{stvid_r,stvid_r}:{osd_pixel, osd_pixel, osd_pixel, stvid_r}; -assign video_g = !osd_oe?{stvid_g,stvid_g}:{osd_pixel, osd_pixel, 1'b1, stvid_g}; -assign video_b = !osd_oe?{stvid_b,stvid_b}:{osd_pixel, osd_pixel, osd_pixel, stvid_b}; +//assign video_r = !osd_oe?{stvid_r,stvid_r}:{osd_pixel, osd_pixel, osd_pixel, stvid_r}; +//assign video_g = !osd_oe?{stvid_g,stvid_g}:{osd_pixel, osd_pixel, 1'b1, stvid_g}; +//assign video_b = !osd_oe?{stvid_b,stvid_b}:{osd_pixel, osd_pixel, osd_pixel, stvid_b}; +always @(posedge clk) begin + video_r <= !osd_oe?{stvid_r,stvid_r}:{osd_pixel, osd_pixel, osd_pixel, stvid_r}; + video_g <= !osd_oe?{stvid_g,stvid_g}:{osd_pixel, osd_pixel, 1'b1, stvid_g}; + video_b <= !osd_oe?{stvid_b,stvid_b}:{osd_pixel, osd_pixel, osd_pixel, stvid_b}; +end // display enable signal // the color modes use a scan doubler and output the data with 2 lines delay