Uploaded_1_25_2020
This commit is contained in:
parent
50099361f5
commit
e4bde7a1f9
|
@ -21,29 +21,51 @@
|
|||
//
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2020 Ted Fried
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
|
||||
module four_module_lockstep
|
||||
(
|
||||
input CORE_CLK, // Core Signals
|
||||
input RST_n,
|
||||
input CORE_CLK, // Core Signals
|
||||
input RST_n,
|
||||
|
||||
|
||||
input [3:0] KILL_MODE,
|
||||
input [3:0] PB_SWITCH,
|
||||
output [3:0] LEDS,
|
||||
output [3:0] PROBE,
|
||||
|
||||
input UART_RX, // UART
|
||||
output UART_TX,
|
||||
output SPEAKER
|
||||
|
||||
|
||||
input [3:0] KILL_MODE,
|
||||
input [3:0] PB_SWITCH,
|
||||
output [3:0] LEDS,
|
||||
output [3:0] PROBE,
|
||||
|
||||
input UART_RX, // UART
|
||||
output UART_TX,
|
||||
output SPEAKER
|
||||
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// Internal Signals
|
||||
|
||||
|
@ -123,15 +145,15 @@ assign core_clk_int = CORE_CLK;
|
|||
|
||||
|
||||
|
||||
assign LEDS[3] = ~module3_broadcast_ok;
|
||||
assign LEDS[2] = ~module2_broadcast_ok;
|
||||
assign LEDS[1] = ~module1_broadcast_ok;
|
||||
assign LEDS[0] = ~module0_broadcast_ok;
|
||||
assign LEDS[3] = ~module3_broadcast_ok;
|
||||
assign LEDS[2] = ~module2_broadcast_ok;
|
||||
assign LEDS[1] = ~module1_broadcast_ok;
|
||||
assign LEDS[0] = ~module0_broadcast_ok;
|
||||
|
||||
assign PROBE[3] = ~module3_broadcast_ok;
|
||||
assign PROBE[2] = ~module2_broadcast_ok;
|
||||
assign PROBE[1] = ~module1_broadcast_ok;
|
||||
assign PROBE[0] = ~module0_broadcast_ok;
|
||||
assign PROBE[3] = ~module3_broadcast_ok;
|
||||
assign PROBE[2] = ~module2_broadcast_ok;
|
||||
assign PROBE[1] = ~module1_broadcast_ok;
|
||||
assign PROBE[0] = ~module0_broadcast_ok;
|
||||
|
||||
assign SPEAKER = speaker_int_d3;
|
||||
|
||||
|
@ -177,207 +199,207 @@ begin : BUTTON_DEBOUNCE
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Lockstep Modules
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
module_block MODULE0
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
module_block MODULE0
|
||||
(
|
||||
.CORE_CLK (core_clk_int),
|
||||
.RST_n (rst_n_d4),
|
||||
.KILL (kill0),
|
||||
.KILL_MODE (kmode_d4),
|
||||
.MODULE_ID (2'h0),
|
||||
|
||||
.BROADCAST_OK (module0_broadcast_ok),
|
||||
.BROADCAST_STROBE (module0_strobe),
|
||||
.BROADCAST_ADDRESS (module0_address),
|
||||
.BROADCAST_DATA (module0_data),
|
||||
.BROADCAST_IP (module0_ip),
|
||||
.BROADCAST_SYNC (module0_sync),
|
||||
.BROADCAST_IDSBL (module0_idsbl),
|
||||
.CORE_CLK (core_clk_int),
|
||||
.RST_n (rst_n_d4),
|
||||
.KILL (kill0),
|
||||
.KILL_MODE (kmode_d4),
|
||||
.MODULE_ID (2'h0),
|
||||
|
||||
.BROADCAST_OK (module0_broadcast_ok),
|
||||
.BROADCAST_STROBE (module0_strobe),
|
||||
.BROADCAST_ADDRESS (module0_address),
|
||||
.BROADCAST_DATA (module0_data),
|
||||
.BROADCAST_IP (module0_ip),
|
||||
.BROADCAST_SYNC (module0_sync),
|
||||
.BROADCAST_IDSBL (module0_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN0 (module1_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN0 (module1_strobe),
|
||||
.BROADCAST_ADDRESS_IN0 (module1_address),
|
||||
.BROADCAST_DATA_IN0 (module1_data),
|
||||
.BROADCAST_IP_IN0 (module1_ip),
|
||||
.BROADCAST_SYNC_IN0 (module1_sync),
|
||||
.BROADCAST_IDSBL_IN0 (module1_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN1 (module2_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN1 (module2_strobe),
|
||||
.BROADCAST_ADDRESS_IN1 (module2_address),
|
||||
.BROADCAST_DATA_IN1 (module2_data),
|
||||
.BROADCAST_IP_IN1 (module2_ip),
|
||||
.BROADCAST_SYNC_IN1 (module2_sync),
|
||||
.BROADCAST_IDSBL_IN1 (module2_idsbl),
|
||||
.BROADCAST_OK_IN0 (module1_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN0 (module1_strobe),
|
||||
.BROADCAST_ADDRESS_IN0 (module1_address),
|
||||
.BROADCAST_DATA_IN0 (module1_data),
|
||||
.BROADCAST_IP_IN0 (module1_ip),
|
||||
.BROADCAST_SYNC_IN0 (module1_sync),
|
||||
.BROADCAST_IDSBL_IN0 (module1_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN1 (module2_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN1 (module2_strobe),
|
||||
.BROADCAST_ADDRESS_IN1 (module2_address),
|
||||
.BROADCAST_DATA_IN1 (module2_data),
|
||||
.BROADCAST_IP_IN1 (module2_ip),
|
||||
.BROADCAST_SYNC_IN1 (module2_sync),
|
||||
.BROADCAST_IDSBL_IN1 (module2_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN2 (module3_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN2 (module3_strobe),
|
||||
.BROADCAST_ADDRESS_IN2 (module3_address),
|
||||
.BROADCAST_DATA_IN2 (module3_data),
|
||||
.BROADCAST_IP_IN2 (module3_ip),
|
||||
.BROADCAST_SYNC_IN2 (module3_sync),
|
||||
.BROADCAST_IDSBL_IN2 (module3_idsbl),
|
||||
.BROADCAST_OK_IN2 (module3_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN2 (module3_strobe),
|
||||
.BROADCAST_ADDRESS_IN2 (module3_address),
|
||||
.BROADCAST_DATA_IN2 (module3_data),
|
||||
.BROADCAST_IP_IN2 (module3_ip),
|
||||
.BROADCAST_SYNC_IN2 (module3_sync),
|
||||
.BROADCAST_IDSBL_IN2 (module3_idsbl),
|
||||
|
||||
. INT2 (interrupt2),
|
||||
. INT3 (interrupt3),
|
||||
. INT2 (interrupt2),
|
||||
. INT3 (interrupt3),
|
||||
|
||||
.PROXY_RD_DATA (proxy_rd_data_int)
|
||||
.PROXY_RD_DATA (proxy_rd_data_int)
|
||||
|
||||
);
|
||||
);
|
||||
|
||||
|
||||
module_block MODULE1
|
||||
|
||||
module_block MODULE1
|
||||
(
|
||||
.CORE_CLK (core_clk_int),
|
||||
.RST_n (rst_n_d4),
|
||||
.KILL (kill1),
|
||||
.KILL_MODE (kmode_d4),
|
||||
.MODULE_ID (2'h1),
|
||||
|
||||
.BROADCAST_OK (module1_broadcast_ok),
|
||||
.BROADCAST_STROBE (module1_strobe),
|
||||
.BROADCAST_ADDRESS (module1_address),
|
||||
.BROADCAST_DATA (module1_data),
|
||||
.BROADCAST_IP (module1_ip),
|
||||
.BROADCAST_SYNC (module1_sync),
|
||||
.BROADCAST_IDSBL (module1_idsbl),
|
||||
.CORE_CLK (core_clk_int),
|
||||
.RST_n (rst_n_d4),
|
||||
.KILL (kill1),
|
||||
.KILL_MODE (kmode_d4),
|
||||
.MODULE_ID (2'h1),
|
||||
|
||||
.BROADCAST_OK (module1_broadcast_ok),
|
||||
.BROADCAST_STROBE (module1_strobe),
|
||||
.BROADCAST_ADDRESS (module1_address),
|
||||
.BROADCAST_DATA (module1_data),
|
||||
.BROADCAST_IP (module1_ip),
|
||||
.BROADCAST_SYNC (module1_sync),
|
||||
.BROADCAST_IDSBL (module1_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN0 (module2_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN0 (module2_strobe),
|
||||
.BROADCAST_ADDRESS_IN0 (module2_address),
|
||||
.BROADCAST_DATA_IN0 (module2_data),
|
||||
.BROADCAST_IP_IN0 (module2_ip),
|
||||
.BROADCAST_SYNC_IN0 (module2_sync),
|
||||
.BROADCAST_IDSBL_IN0 (module2_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN1 (module3_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN1 (module3_strobe),
|
||||
.BROADCAST_ADDRESS_IN1 (module3_address),
|
||||
.BROADCAST_DATA_IN1 (module3_data),
|
||||
.BROADCAST_IP_IN1 (module3_ip),
|
||||
.BROADCAST_SYNC_IN1 (module3_sync),
|
||||
.BROADCAST_IDSBL_IN1 (module3_idsbl),
|
||||
.BROADCAST_OK_IN0 (module2_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN0 (module2_strobe),
|
||||
.BROADCAST_ADDRESS_IN0 (module2_address),
|
||||
.BROADCAST_DATA_IN0 (module2_data),
|
||||
.BROADCAST_IP_IN0 (module2_ip),
|
||||
.BROADCAST_SYNC_IN0 (module2_sync),
|
||||
.BROADCAST_IDSBL_IN0 (module2_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN1 (module3_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN1 (module3_strobe),
|
||||
.BROADCAST_ADDRESS_IN1 (module3_address),
|
||||
.BROADCAST_DATA_IN1 (module3_data),
|
||||
.BROADCAST_IP_IN1 (module3_ip),
|
||||
.BROADCAST_SYNC_IN1 (module3_sync),
|
||||
.BROADCAST_IDSBL_IN1 (module3_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN2 (module0_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN2 (module0_strobe),
|
||||
.BROADCAST_ADDRESS_IN2 (module0_address),
|
||||
.BROADCAST_DATA_IN2 (module0_data),
|
||||
.BROADCAST_IP_IN2 (module0_ip),
|
||||
.BROADCAST_SYNC_IN2 (module0_sync),
|
||||
.BROADCAST_IDSBL_IN2 (module0_idsbl),
|
||||
.BROADCAST_OK_IN2 (module0_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN2 (module0_strobe),
|
||||
.BROADCAST_ADDRESS_IN2 (module0_address),
|
||||
.BROADCAST_DATA_IN2 (module0_data),
|
||||
.BROADCAST_IP_IN2 (module0_ip),
|
||||
.BROADCAST_SYNC_IN2 (module0_sync),
|
||||
.BROADCAST_IDSBL_IN2 (module0_idsbl),
|
||||
|
||||
. INT2 (interrupt2),
|
||||
. INT3 (interrupt3),
|
||||
. INT2 (interrupt2),
|
||||
. INT3 (interrupt3),
|
||||
|
||||
.PROXY_RD_DATA (proxy_rd_data_int)
|
||||
.PROXY_RD_DATA (proxy_rd_data_int)
|
||||
|
||||
);
|
||||
);
|
||||
|
||||
|
||||
module_block MODULE2
|
||||
|
||||
module_block MODULE2
|
||||
(
|
||||
.CORE_CLK (core_clk_int),
|
||||
.RST_n (rst_n_d4),
|
||||
.KILL (kill2),
|
||||
.KILL_MODE (kmode_d4),
|
||||
.MODULE_ID (2'h2),
|
||||
|
||||
.BROADCAST_OK (module2_broadcast_ok),
|
||||
.BROADCAST_STROBE (module2_strobe),
|
||||
.BROADCAST_ADDRESS (module2_address),
|
||||
.BROADCAST_DATA (module2_data),
|
||||
.BROADCAST_IP (module2_ip),
|
||||
.BROADCAST_SYNC (module2_sync),
|
||||
.BROADCAST_IDSBL (module2_idsbl),
|
||||
.CORE_CLK (core_clk_int),
|
||||
.RST_n (rst_n_d4),
|
||||
.KILL (kill2),
|
||||
.KILL_MODE (kmode_d4),
|
||||
.MODULE_ID (2'h2),
|
||||
|
||||
.BROADCAST_OK (module2_broadcast_ok),
|
||||
.BROADCAST_STROBE (module2_strobe),
|
||||
.BROADCAST_ADDRESS (module2_address),
|
||||
.BROADCAST_DATA (module2_data),
|
||||
.BROADCAST_IP (module2_ip),
|
||||
.BROADCAST_SYNC (module2_sync),
|
||||
.BROADCAST_IDSBL (module2_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN0 (module3_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN0 (module3_strobe),
|
||||
.BROADCAST_ADDRESS_IN0 (module3_address),
|
||||
.BROADCAST_DATA_IN0 (module3_data),
|
||||
.BROADCAST_IP_IN0 (module3_ip),
|
||||
.BROADCAST_SYNC_IN0 (module3_sync),
|
||||
.BROADCAST_IDSBL_IN0 (module3_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN1 (module0_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN1 (module0_strobe),
|
||||
.BROADCAST_ADDRESS_IN1 (module0_address),
|
||||
.BROADCAST_DATA_IN1 (module0_data),
|
||||
.BROADCAST_IP_IN1 (module0_ip),
|
||||
.BROADCAST_SYNC_IN1 (module0_sync),
|
||||
.BROADCAST_IDSBL_IN1 (module0_idsbl),
|
||||
.BROADCAST_OK_IN0 (module3_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN0 (module3_strobe),
|
||||
.BROADCAST_ADDRESS_IN0 (module3_address),
|
||||
.BROADCAST_DATA_IN0 (module3_data),
|
||||
.BROADCAST_IP_IN0 (module3_ip),
|
||||
.BROADCAST_SYNC_IN0 (module3_sync),
|
||||
.BROADCAST_IDSBL_IN0 (module3_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN1 (module0_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN1 (module0_strobe),
|
||||
.BROADCAST_ADDRESS_IN1 (module0_address),
|
||||
.BROADCAST_DATA_IN1 (module0_data),
|
||||
.BROADCAST_IP_IN1 (module0_ip),
|
||||
.BROADCAST_SYNC_IN1 (module0_sync),
|
||||
.BROADCAST_IDSBL_IN1 (module0_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN2 (module1_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN2 (module1_strobe),
|
||||
.BROADCAST_ADDRESS_IN2 (module1_address),
|
||||
.BROADCAST_DATA_IN2 (module1_data),
|
||||
.BROADCAST_IP_IN2 (module1_ip),
|
||||
.BROADCAST_SYNC_IN2 (module1_sync),
|
||||
.BROADCAST_IDSBL_IN2 (module1_idsbl),
|
||||
.BROADCAST_OK_IN2 (module1_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN2 (module1_strobe),
|
||||
.BROADCAST_ADDRESS_IN2 (module1_address),
|
||||
.BROADCAST_DATA_IN2 (module1_data),
|
||||
.BROADCAST_IP_IN2 (module1_ip),
|
||||
.BROADCAST_SYNC_IN2 (module1_sync),
|
||||
.BROADCAST_IDSBL_IN2 (module1_idsbl),
|
||||
|
||||
. INT2 (interrupt2),
|
||||
. INT3 (interrupt3),
|
||||
. INT2 (interrupt2),
|
||||
. INT3 (interrupt3),
|
||||
|
||||
.PROXY_RD_DATA (proxy_rd_data_int)
|
||||
.PROXY_RD_DATA (proxy_rd_data_int)
|
||||
|
||||
);
|
||||
);
|
||||
|
||||
|
||||
module_block MODULE3
|
||||
|
||||
module_block MODULE3
|
||||
(
|
||||
.CORE_CLK (core_clk_int),
|
||||
.RST_n (rst_n_d4),
|
||||
.KILL (kill3),
|
||||
.KILL_MODE (kmode_d4),
|
||||
.MODULE_ID (2'h3),
|
||||
|
||||
.BROADCAST_OK (module3_broadcast_ok),
|
||||
.BROADCAST_STROBE (module3_strobe),
|
||||
.BROADCAST_ADDRESS (module3_address),
|
||||
.BROADCAST_DATA (module3_data),
|
||||
.BROADCAST_IP (module3_ip),
|
||||
.BROADCAST_SYNC (module3_sync),
|
||||
.BROADCAST_IDSBL (module3_idsbl),
|
||||
.CORE_CLK (core_clk_int),
|
||||
.RST_n (rst_n_d4),
|
||||
.KILL (kill3),
|
||||
.KILL_MODE (kmode_d4),
|
||||
.MODULE_ID (2'h3),
|
||||
|
||||
.BROADCAST_OK (module3_broadcast_ok),
|
||||
.BROADCAST_STROBE (module3_strobe),
|
||||
.BROADCAST_ADDRESS (module3_address),
|
||||
.BROADCAST_DATA (module3_data),
|
||||
.BROADCAST_IP (module3_ip),
|
||||
.BROADCAST_SYNC (module3_sync),
|
||||
.BROADCAST_IDSBL (module3_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN0 (module0_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN0 (module0_strobe),
|
||||
.BROADCAST_ADDRESS_IN0 (module0_address),
|
||||
.BROADCAST_DATA_IN0 (module0_data),
|
||||
.BROADCAST_IP_IN0 (module0_ip),
|
||||
.BROADCAST_SYNC_IN0 (module0_sync),
|
||||
.BROADCAST_IDSBL_IN0 (module0_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN1 (module1_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN1 (module1_strobe),
|
||||
.BROADCAST_ADDRESS_IN1 (module1_address),
|
||||
.BROADCAST_DATA_IN1 (module1_data),
|
||||
.BROADCAST_IP_IN1 (module1_ip),
|
||||
.BROADCAST_SYNC_IN1 (module1_sync),
|
||||
.BROADCAST_IDSBL_IN1 (module1_idsbl),
|
||||
.BROADCAST_OK_IN0 (module0_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN0 (module0_strobe),
|
||||
.BROADCAST_ADDRESS_IN0 (module0_address),
|
||||
.BROADCAST_DATA_IN0 (module0_data),
|
||||
.BROADCAST_IP_IN0 (module0_ip),
|
||||
.BROADCAST_SYNC_IN0 (module0_sync),
|
||||
.BROADCAST_IDSBL_IN0 (module0_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN1 (module1_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN1 (module1_strobe),
|
||||
.BROADCAST_ADDRESS_IN1 (module1_address),
|
||||
.BROADCAST_DATA_IN1 (module1_data),
|
||||
.BROADCAST_IP_IN1 (module1_ip),
|
||||
.BROADCAST_SYNC_IN1 (module1_sync),
|
||||
.BROADCAST_IDSBL_IN1 (module1_idsbl),
|
||||
|
||||
.BROADCAST_OK_IN2 (module2_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN2 (module2_strobe),
|
||||
.BROADCAST_ADDRESS_IN2 (module2_address),
|
||||
.BROADCAST_DATA_IN2 (module2_data),
|
||||
.BROADCAST_IP_IN2 (module2_ip),
|
||||
.BROADCAST_SYNC_IN2 (module2_sync),
|
||||
.BROADCAST_IDSBL_IN2 (module2_idsbl),
|
||||
.BROADCAST_OK_IN2 (module2_broadcast_ok),
|
||||
.BROADCAST_STROBE_IN2 (module2_strobe),
|
||||
.BROADCAST_ADDRESS_IN2 (module2_address),
|
||||
.BROADCAST_DATA_IN2 (module2_data),
|
||||
.BROADCAST_IP_IN2 (module2_ip),
|
||||
.BROADCAST_SYNC_IN2 (module2_sync),
|
||||
.BROADCAST_IDSBL_IN2 (module2_idsbl),
|
||||
|
||||
. INT2 (interrupt2),
|
||||
. INT3 (interrupt3),
|
||||
. INT2 (interrupt2),
|
||||
. INT3 (interrupt3),
|
||||
|
||||
.PROXY_RD_DATA (proxy_rd_data_int)
|
||||
.PROXY_RD_DATA (proxy_rd_data_int)
|
||||
|
||||
);
|
||||
);
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// Fixed-priority arbiter that chooses which
|
||||
// core's outputs to direct to the peripherals.
|
||||
|
@ -387,23 +409,23 @@ assign top_strobe = (module0_broadcast_ok==1'b1) ? module0_strobe :
|
|||
(module1_broadcast_ok==1'b1) ? module1_strobe :
|
||||
(module2_broadcast_ok==1'b1) ? module2_strobe :
|
||||
(module3_broadcast_ok==1'b1) ? module3_strobe :
|
||||
8'hEE;
|
||||
|
||||
8'hEE;
|
||||
|
||||
|
||||
assign top_address = (module0_broadcast_ok==1'b1) ? module0_address :
|
||||
(module1_broadcast_ok==1'b1) ? module1_address :
|
||||
(module2_broadcast_ok==1'b1) ? module2_address :
|
||||
(module3_broadcast_ok==1'b1) ? module3_address :
|
||||
16'hEEEE;
|
||||
|
||||
|
||||
16'hEEEE;
|
||||
|
||||
|
||||
|
||||
assign top_data = (module0_broadcast_ok==1'b1) ? module0_data :
|
||||
(module1_broadcast_ok==1'b1) ? module1_data :
|
||||
(module2_broadcast_ok==1'b1) ? module2_data :
|
||||
(module3_broadcast_ok==1'b1) ? module3_data :
|
||||
8'hEE;
|
||||
|
||||
8'hEE;
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -422,39 +444,39 @@ begin : PROXY_ADDRESSING
|
|||
|
||||
if (rst_n_d4==1'b0)
|
||||
begin
|
||||
proxy_wr <= 'h0;
|
||||
proxy_rd <= 'h0;
|
||||
proxy_address <= 'h0;
|
||||
prody_wr_data <= 'h0;
|
||||
proxy_wr <= 'h0;
|
||||
proxy_rd <= 'h0;
|
||||
proxy_address <= 'h0;
|
||||
prody_wr_data <= 'h0;
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
|
||||
if (top_strobe[7:0]==8'h11 && top_address[15:0]==16'h00C1)
|
||||
begin
|
||||
proxy_wr <= 1'b1;
|
||||
prody_wr_data <= top_data;
|
||||
end
|
||||
|
||||
if (top_strobe[7:0]==8'h11 && top_address[15:0]==16'h00C1)
|
||||
begin
|
||||
proxy_wr <= 1'b1;
|
||||
prody_wr_data <= top_data;
|
||||
end
|
||||
else
|
||||
begin
|
||||
proxy_wr <= 1'b0;
|
||||
end
|
||||
|
||||
if (top_strobe[7:0]==8'h11 && top_address[15:0]==16'h00C2)
|
||||
begin
|
||||
proxy_rd <= 1'b1;
|
||||
proxy_address <= top_data;
|
||||
end
|
||||
begin
|
||||
proxy_wr <= 1'b0;
|
||||
end
|
||||
|
||||
if (top_strobe[7:0]==8'h11 && top_address[15:0]==16'h00C2)
|
||||
begin
|
||||
proxy_rd <= 1'b1;
|
||||
proxy_address <= top_data;
|
||||
end
|
||||
else
|
||||
begin
|
||||
proxy_rd <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
begin
|
||||
proxy_rd <= 1'b0;
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
|
@ -471,14 +493,14 @@ end
|
|||
|
||||
// Steer the peripheral read data back to the modules
|
||||
//
|
||||
assign proxy_rd_data_int = (proxy_address[7:4]==4'h0) ? timer_dataout :
|
||||
(proxy_address[7:4]==4'h1) ? uart_dataout :
|
||||
8'hEE ;
|
||||
|
||||
assign proxy_rd_data_int = (proxy_address[7:4]==4'h0) ? timer_dataout :
|
||||
(proxy_address[7:4]==4'h1) ? uart_dataout :
|
||||
8'hEE ;
|
||||
|
||||
// Gate the peripheral read and write strobes
|
||||
assign timer_wr_strobe = (proxy_address[7:4]==4'h0) ? proxy_wr : 1'b0;
|
||||
assign uart_wr_strobe = (proxy_address[7:4]==4'h1) ? proxy_wr : 1'b0;
|
||||
assign uart_rd_strobe = (proxy_address[7:4]==4'h1) ? proxy_rd : 1'b0;
|
||||
assign timer_wr_strobe = (proxy_address[7:4]==4'h0) ? proxy_wr : 1'b0;
|
||||
assign uart_wr_strobe = (proxy_address[7:4]==4'h1) ? proxy_wr : 1'b0;
|
||||
assign uart_rd_strobe = (proxy_address[7:4]==4'h1) ? proxy_rd : 1'b0;
|
||||
|
||||
|
||||
|
||||
|
@ -490,40 +512,40 @@ assign uart_rd_strobe = (proxy_address[7:4]==4'h1) ? proxy_rd : 1'b0;
|
|||
// Timer-0 = Frequency generator
|
||||
// Timer-1 = Pulse generator
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
timer TIMER
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
timer TIMER
|
||||
(
|
||||
.CORE_CLK (core_clk_int),
|
||||
.RST_n (rst_n_d4),
|
||||
.ADDRESS (proxy_address[3:0]),
|
||||
.DATA_IN (prody_wr_data),
|
||||
.DATA_OUT (timer_dataout),
|
||||
.STROBE_WR (timer_wr_strobe),
|
||||
.TIMER0_OUT (speaker_int),
|
||||
.TIMER1_OUT (interrupt2)
|
||||
.CORE_CLK (core_clk_int),
|
||||
.RST_n (rst_n_d4),
|
||||
.ADDRESS (proxy_address[3:0]),
|
||||
.DATA_IN (prody_wr_data),
|
||||
.DATA_OUT (timer_dataout),
|
||||
.STROBE_WR (timer_wr_strobe),
|
||||
.TIMER0_OUT (speaker_int),
|
||||
.TIMER1_OUT (interrupt2)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// UART - Fixed 9600 baud
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
uart UART
|
||||
uart UART
|
||||
(
|
||||
.CLK (core_clk_int),
|
||||
.RST_n (rst_n_d4),
|
||||
.ADDRESS (proxy_address[1:0]),
|
||||
.DATA_IN (prody_wr_data),
|
||||
.DATA_OUT (uart_dataout),
|
||||
.STROBE_RD (uart_rd_strobe),
|
||||
.STROBE_WR (uart_wr_strobe),
|
||||
.UART_RX (UART_RX),
|
||||
.UART_TX (UART_TX),
|
||||
.UART_INT (interrupt3)
|
||||
.CLK (core_clk_int),
|
||||
.RST_n (rst_n_d4),
|
||||
.ADDRESS (proxy_address[1:0]),
|
||||
.DATA_IN (prody_wr_data),
|
||||
.DATA_OUT (uart_dataout),
|
||||
.STROBE_RD (uart_rd_strobe),
|
||||
.STROBE_WR (uart_wr_strobe),
|
||||
.UART_RX (UART_RX),
|
||||
.UART_TX (UART_TX),
|
||||
.UART_INT (interrupt3)
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,28 @@
|
|||
//
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2020 Ted Fried
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
|
@ -49,7 +71,7 @@ module module_block
|
|||
input [7:0] BROADCAST_DATA_IN0,
|
||||
input [15:0] BROADCAST_IP_IN0,
|
||||
input BROADCAST_SYNC_IN0,
|
||||
input BROADCAST_IDSBL_IN0,
|
||||
input BROADCAST_IDSBL_IN0,
|
||||
|
||||
input BROADCAST_OK_IN1,
|
||||
input [7:0] BROADCAST_STROBE_IN1,
|
||||
|
@ -57,7 +79,7 @@ module module_block
|
|||
input [7:0] BROADCAST_DATA_IN1,
|
||||
input [15:0] BROADCAST_IP_IN1,
|
||||
input BROADCAST_SYNC_IN1,
|
||||
input BROADCAST_IDSBL_IN1,
|
||||
input BROADCAST_IDSBL_IN1,
|
||||
|
||||
input BROADCAST_OK_IN2,
|
||||
input [7:0] BROADCAST_STROBE_IN2,
|
||||
|
@ -65,7 +87,7 @@ module module_block
|
|||
input [7:0] BROADCAST_DATA_IN2,
|
||||
input [15:0] BROADCAST_IP_IN2,
|
||||
input BROADCAST_SYNC_IN2,
|
||||
input BROADCAST_IDSBL_IN2,
|
||||
input BROADCAST_IDSBL_IN2,
|
||||
|
||||
|
||||
|
||||
|
@ -268,7 +290,7 @@ assign BROADCAST_DATA = ((KILL_MODE==4'h2 && kill_d4==1'b1) || (run_level!
|
|||
assign BROADCAST_IP = eu_register_ip;
|
||||
assign BROADCAST_STROBE = (run_level!=2'h3) ? { 6'h0 , MODULE_ID } : eu_biu_strobe;
|
||||
assign BROADCAST_SYNC = (eu_rom_address==9'h103) ? 1'b1 : 1'b0;
|
||||
assign BROADCAST_IDSBL = core_interrupt_disable;
|
||||
assign BROADCAST_IDSBL = core_interrupt_disable;
|
||||
|
||||
|
||||
|
||||
|
@ -589,12 +611,12 @@ kill_d4 <= kill_d3;
|
|||
|
||||
|
||||
// Register writeback
|
||||
if (run_level==2'h1)
|
||||
begin
|
||||
if (run_level==2'h1)
|
||||
begin
|
||||
eu_register_ip <= rebuild_ip_in;
|
||||
eu_biu_strobe <= 'h0;
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
else if (eu_stall_pipeline==1'b0 && eu_opcode_type!=3'h0 && eu_opcode_type!=3'h1)
|
||||
begin
|
||||
eu_alu_last_result <= eu_alu_out[15:0];
|
||||
|
@ -645,14 +667,14 @@ kill_d4 <= kill_d3;
|
|||
else
|
||||
begin
|
||||
eu_stall_pipeline <= 1'b0; // Debounce the pipeline stall
|
||||
if (KILL_MODE==4'h1 && kill_d4==1'b1)
|
||||
begin
|
||||
eu_rom_address <= 'h0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
eu_rom_address <= eu_rom_address + 1'b1;
|
||||
end
|
||||
if (KILL_MODE==4'h1 && kill_d4==1'b1)
|
||||
begin
|
||||
eu_rom_address <= 'h0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
eu_rom_address <= eu_rom_address + 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -683,7 +705,7 @@ begin : BIU_CONTROLLER
|
|||
rebuild_addr_out <= 'h0;
|
||||
rebuild_addr_out_d <= 'h0;
|
||||
rebuild_cross_zero <= 'h0;
|
||||
run_level <= 'h3;
|
||||
run_level <= 'h3;
|
||||
end
|
||||
|
||||
else
|
||||
|
@ -691,16 +713,16 @@ begin : BIU_CONTROLLER
|
|||
|
||||
// Delay address out by one clock to line up with the broadcast data
|
||||
if (KILL_MODE==4'h5 && kill_d4==1'b1)
|
||||
begin
|
||||
rebuild_addr_out_d <= 'h0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
rebuild_addr_out_d <= rebuild_addr_out;
|
||||
end
|
||||
|
||||
// Pipeline the neighboring code SYNC pulse
|
||||
rebuild_sync_in_d1 <= rebuild_sync_in;
|
||||
begin
|
||||
rebuild_addr_out_d <= 'h0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
rebuild_addr_out_d <= rebuild_addr_out;
|
||||
end
|
||||
|
||||
// Pipeline the neighboring code SYNC pulse
|
||||
rebuild_sync_in_d1 <= rebuild_sync_in;
|
||||
rebuild_sync_in_d2 <= rebuild_sync_in_d1;
|
||||
rebuild_sync_in_d3 <= rebuild_sync_in_d2;
|
||||
|
||||
|
@ -721,17 +743,17 @@ begin : BIU_CONTROLLER
|
|||
end
|
||||
|
||||
|
||||
// Allow four passes of the full range or memory and register addresses when rebuilding a module
|
||||
// Allow four passes of the full range or memory and register addresses when rebuilding a module
|
||||
if (run_level==2'h3)
|
||||
begin
|
||||
begin
|
||||
rebuild_cross_zero <= 'h0;
|
||||
end
|
||||
end
|
||||
else if (run_level==2'h0 && rebuild_addr=='h0)
|
||||
begin
|
||||
rebuild_cross_zero <= rebuild_cross_zero + 1'b1;
|
||||
end
|
||||
|
||||
|
||||
|
||||
// If Voter has detected a failure and module is not currently in rebuilding mode, then enter rebuilding mode.
|
||||
if ( run_level==2'h3 && voter_good==1'b0)
|
||||
begin
|
||||
|
@ -757,12 +779,12 @@ begin : BIU_CONTROLLER
|
|||
|
||||
|
||||
eu_register_r3_d1 <= eu_register_r3;
|
||||
|
||||
|
||||
if (run_level==2'h2)
|
||||
begin
|
||||
core_interrupt_disable <= neighbor_idsbl;
|
||||
end
|
||||
else if (eu_biu_strobe_int==3'h3)
|
||||
begin
|
||||
core_interrupt_disable <= neighbor_idsbl;
|
||||
end
|
||||
else if (eu_biu_strobe_int==3'h3)
|
||||
begin
|
||||
core_interrupt_disable <= 1'b1;
|
||||
end
|
||||
|
|
|
@ -21,20 +21,42 @@
|
|||
//
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2020 Ted Fried
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
module MCL51_top
|
||||
(
|
||||
input CLK,
|
||||
input RESET_n,
|
||||
input CLK,
|
||||
input RESET_n,
|
||||
|
||||
input UART_RX,
|
||||
output UART_TX,
|
||||
output SPEAKER
|
||||
input UART_RX,
|
||||
output UART_TX,
|
||||
output SPEAKER
|
||||
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// Internal Signals
|
||||
|
||||
|
@ -58,57 +80,57 @@ wire [7:0] t_biu_return_data;
|
|||
assign clk_int = CLK;
|
||||
assign t_rst_n_int = (t_biu_reset_out==1'b0 && RESET_n==1'b1) ? 1'b1 : 1'b0;
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// EU Core
|
||||
//------------------------------------------------------------------------
|
||||
eu EU_CORE
|
||||
eu EU_CORE
|
||||
(
|
||||
.CORE_CLK (clk_int),
|
||||
.RST_n (t_rst_n_int),
|
||||
|
||||
.EU_BIU_STROBE (t_eu_biu_strobe),
|
||||
.EU_BIU_DATAOUT (t_eu_biu_dataout),
|
||||
.EU_REGISTER_R3 (t_eu_register_r3),
|
||||
.EU_REGISTER_IP (t_eu_register_ip),
|
||||
|
||||
.BIU_SFR_ACC (t_biu_sfr_acc),
|
||||
.BIU_SFR_DPTR (t_biu_sfr_dptr),
|
||||
.BIU_SFR_SP (t_biu_sfr_sp),
|
||||
.BIU_SFR_PSW (t_biu_sfr_psw),
|
||||
.BIU_RETURN_DATA (t_biu_return_data),
|
||||
.BIU_INTERRUPT (t_biu_interrupt)
|
||||
.CORE_CLK (clk_int),
|
||||
.RST_n (t_rst_n_int),
|
||||
|
||||
.EU_BIU_STROBE (t_eu_biu_strobe),
|
||||
.EU_BIU_DATAOUT (t_eu_biu_dataout),
|
||||
.EU_REGISTER_R3 (t_eu_register_r3),
|
||||
.EU_REGISTER_IP (t_eu_register_ip),
|
||||
|
||||
.BIU_SFR_ACC (t_biu_sfr_acc),
|
||||
.BIU_SFR_DPTR (t_biu_sfr_dptr),
|
||||
.BIU_SFR_SP (t_biu_sfr_sp),
|
||||
.BIU_SFR_PSW (t_biu_sfr_psw),
|
||||
.BIU_RETURN_DATA (t_biu_return_data),
|
||||
.BIU_INTERRUPT (t_biu_interrupt)
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// BIU Core
|
||||
//------------------------------------------------------------------------
|
||||
biu BIU_CORE
|
||||
biu BIU_CORE
|
||||
(
|
||||
.CORE_CLK (clk_int),
|
||||
.RST_n (t_rst_n_int),
|
||||
.UART_RX (UART_RX),
|
||||
.UART_TX (UART_TX),
|
||||
.SPEAKER (SPEAKER),
|
||||
.EU_BIU_STROBE (t_eu_biu_strobe),
|
||||
.EU_BIU_DATAOUT (t_eu_biu_dataout),
|
||||
.EU_REGISTER_R3 (t_eu_register_r3),
|
||||
.EU_REGISTER_IP (t_eu_register_ip),
|
||||
.BIU_SFR_ACC (t_biu_sfr_acc),
|
||||
.BIU_SFR_DPTR (t_biu_sfr_dptr),
|
||||
.BIU_SFR_SP (t_biu_sfr_sp),
|
||||
.BIU_SFR_PSW (t_biu_sfr_psw),
|
||||
.BIU_RETURN_DATA (t_biu_return_data),
|
||||
.BIU_INTERRUPT (t_biu_interrupt),
|
||||
.RESET_OUT (t_biu_reset_out)
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
.CORE_CLK (clk_int),
|
||||
.RST_n (t_rst_n_int),
|
||||
.UART_RX (UART_RX),
|
||||
.UART_TX (UART_TX),
|
||||
.SPEAKER (SPEAKER),
|
||||
.EU_BIU_STROBE (t_eu_biu_strobe),
|
||||
.EU_BIU_DATAOUT (t_eu_biu_dataout),
|
||||
.EU_REGISTER_R3 (t_eu_register_r3),
|
||||
.EU_REGISTER_IP (t_eu_register_ip),
|
||||
.BIU_SFR_ACC (t_biu_sfr_acc),
|
||||
.BIU_SFR_DPTR (t_biu_sfr_dptr),
|
||||
.BIU_SFR_SP (t_biu_sfr_sp),
|
||||
.BIU_SFR_PSW (t_biu_sfr_psw),
|
||||
.BIU_RETURN_DATA (t_biu_return_data),
|
||||
.BIU_INTERRUPT (t_biu_interrupt),
|
||||
.RESET_OUT (t_biu_reset_out)
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,111 +1,144 @@
|
|||
#
|
||||
# Microcode for the MCL51
|
||||
#
|
||||
# ------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2019 by Ted Fried info@MicroCoreLabs.com
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted, provided
|
||||
# that the above copyright notice appear in all copies and that both that
|
||||
# copyright notice and this permission notice appear in supporting documentation.
|
||||
# This software is provided "as is" without express or implied warranty.
|
||||
#
|
||||
# ------------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
#
|
||||
# [15:8]=Internal Flags and system signals [7:0]=Actual PSW register from the BIU
|
||||
# ** Flags must be written to the PSW through the BIU - User could access PSW by address at any time
|
||||
#
|
||||
# assign eu_flags_r[15] = eu_add_carry
|
||||
# assign eu_flags_r[14] = eu_add_aux_carry
|
||||
# assign eu_flags_r[13] = eu_add_carry16
|
||||
# assign eu_flags_r[12] =
|
||||
# assign eu_flags_r[11] =
|
||||
# assign eu_flags_r[10] = eu_add_overflow
|
||||
# assign eu_flags_r[9] =
|
||||
# assign eu_flags_r[8] = BIU_INTERRUPT
|
||||
#
|
||||
# assign eu_flags_r[7] = BIU_SFR_PSW[7] // C
|
||||
# assign eu_flags_r[6] = BIU_SFR_PSW[6] // AC
|
||||
# assign eu_flags_r[5] = BIU_SFR_PSW[5] // F0
|
||||
# assign eu_flags_r[4] = BIU_SFR_PSW[4] // RS1
|
||||
# assign eu_flags_r[3] = BIU_SFR_PSW[3] // RS0
|
||||
# assign eu_flags_r[2] = BIU_SFR_PSW[2] // Overflow
|
||||
# assign eu_flags_r[1] = BIU_INTR // Interrupt from the BIU
|
||||
# assign eu_flags_r[0] = BIU_SFR_PSW[0] // Parity
|
||||
#
|
||||
#
|
||||
#
|
||||
# BIU Strobes
|
||||
# -------------
|
||||
# // Signals from the EU to request BIU processing
|
||||
# // Only asserted for one clock cycle and cause BIU to take immediate action.
|
||||
# //
|
||||
#
|
||||
# eu_biu_address_code = eu_biu_strobe[6:4];
|
||||
# 0=Program code space
|
||||
# 1=Direct Data space
|
||||
# 2=Indirect Data space
|
||||
# 3=SFR or Bit address?
|
||||
#
|
||||
# eu_biu_strobe = eu_biu_strobe[2:0];
|
||||
# 0=idle
|
||||
# 1=write BIU_DATAOUT to address in r3
|
||||
# 2=read address in r3 into BIU_RETURN_DATA
|
||||
# 3=Global Interrupt Disable
|
||||
# 4=Global Interrupt Enable
|
||||
#
|
||||
#
|
||||
# EU Registers
|
||||
# --------------
|
||||
#
|
||||
# Destination Operand0 Operand1
|
||||
# -----------------------------------------------------------------------------------------------
|
||||
# 0 r0 0 r0 0 r0
|
||||
# 1 r1 1 r1 1 r1
|
||||
# 2 r2 2 r2 2 r2
|
||||
# 3 r3 3 r3 3 r3
|
||||
# 4 BIU_Dataout 4 00,BIU_Return_Data 4 00,SP
|
||||
# 5 Dummy 5 {eu_flags_r} 5
|
||||
# 6 BIU_Strobe 6 00,ACC 6 DPTR
|
||||
# 7 IP 7 IP 7 Opcode Immediate[15:0]
|
||||
# 8+ 16'h0000
|
||||
#
|
||||
#
|
||||
# EU Opcodes
|
||||
# -----------
|
||||
# 0x1 - JUMP
|
||||
# ----------------
|
||||
# Bits[31:28] : 0x1
|
||||
# Bits[27:24] : CALL 1=Push next IP address to call stack
|
||||
# Bits[22:20] : Jump Source:
|
||||
# 0x0=Immediate[12:0]
|
||||
# 0x1={4'h0 & code_byte} -- For initial Jump
|
||||
# 0x2={immediate[xx:0] & code_byte[3:0]} -- Addressing modes
|
||||
# 0x3=Return to CALL stored IP address -- CALL Return
|
||||
# 0x4={ 7'h00 , BIU_RETURN_DATA[2:0] } -- Bit Mask decoding table
|
||||
#
|
||||
#
|
||||
# Bits[19:16] : Jump Condition:
|
||||
# 0x0=Unconditional
|
||||
# 0x1=Last_ALU_Result!=0
|
||||
# 0x2=Last_ALU_Result==0
|
||||
# Bits[12:0] : Immediate[12:0]
|
||||
#
|
||||
#
|
||||
# 0x2 - ADD
|
||||
# 0x3 - XOR
|
||||
# 0x4 - OR
|
||||
# 0x5 - AND
|
||||
# 0x6 - Byte swap eu_operand0
|
||||
# 0x7 - Shift Right based on type: { immediate[0] , eu_operand0[7:0] }
|
||||
# Immedaite = 0 = Eight bit - shift in op0[0],
|
||||
# 1 = Eight bit - shift in PSW_carry
|
||||
# 2 = Sixteen bit - shift in eu_add_carry16
|
||||
#
|
||||
|
||||
//
|
||||
//
|
||||
// File Name : Microcode_MCL51.txt
|
||||
// Used on : MCL51
|
||||
// Author : Ted Fried, MicroCore Labs
|
||||
// Creation : 1/25/2020
|
||||
// Code Type : Microcode
|
||||
//
|
||||
// Description:
|
||||
// ============
|
||||
//
|
||||
// Microcode for the MCL51
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Modification History:
|
||||
// =====================
|
||||
//
|
||||
// Revision 1.0 1/25/2020
|
||||
// Initial revision
|
||||
//
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2020 Ted Fried
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// Microcode and microsequencer notes:
|
||||
//
|
||||
|
||||
[15:8]=Internal Flags and system signals [7:0]=Actual PSW register from the BIU
|
||||
** Flags must be written to the PSW through the BIU - User could access PSW by address at any time
|
||||
|
||||
assign eu_flags_r[15] = eu_add_carry
|
||||
assign eu_flags_r[14] = eu_add_aux_carry
|
||||
assign eu_flags_r[13] = eu_add_carry16
|
||||
assign eu_flags_r[12] =
|
||||
assign eu_flags_r[11] =
|
||||
assign eu_flags_r[10] = eu_add_overflow
|
||||
assign eu_flags_r[9] =
|
||||
assign eu_flags_r[8] = BIU_INTERRUPT
|
||||
|
||||
assign eu_flags_r[7] = BIU_SFR_PSW[7] // C
|
||||
assign eu_flags_r[6] = BIU_SFR_PSW[6] // AC
|
||||
assign eu_flags_r[5] = BIU_SFR_PSW[5] // F0
|
||||
assign eu_flags_r[4] = BIU_SFR_PSW[4] // RS1
|
||||
assign eu_flags_r[3] = BIU_SFR_PSW[3] // RS0
|
||||
assign eu_flags_r[2] = BIU_SFR_PSW[2] // Overflow
|
||||
assign eu_flags_r[1] = BIU_INTR // Interrupt from the BIU
|
||||
assign eu_flags_r[0] = BIU_SFR_PSW[0] // Parity
|
||||
|
||||
|
||||
|
||||
BIU Strobes
|
||||
-------------
|
||||
// Signals from the EU to request BIU processing
|
||||
// Only asserted for one clock cycle and cause BIU to take immediate action.
|
||||
//
|
||||
|
||||
eu_biu_address_code = eu_biu_strobe[6:4];
|
||||
0=Program code space
|
||||
1=Direct Data space
|
||||
2=Indirect Data space
|
||||
3=SFR or Bit address?
|
||||
|
||||
eu_biu_strobe = eu_biu_strobe[2:0];
|
||||
0=idle
|
||||
1=write BIU_DATAOUT to address in r3
|
||||
2=read address in r3 into BIU_RETURN_DATA
|
||||
3=Global Interrupt Disable
|
||||
4=Global Interrupt Enable
|
||||
|
||||
|
||||
EU Registers
|
||||
--------------
|
||||
|
||||
Destination Operand0 Operand1
|
||||
-----------------------------------------------------------------------------------------------
|
||||
0 r0 0 r0 0 r0
|
||||
1 r1 1 r1 1 r1
|
||||
2 r2 2 r2 2 r2
|
||||
3 r3 3 r3 3 r3
|
||||
4 BIU_Dataout 4 00,BIU_Return_Data 4 00,SP
|
||||
5 Dummy 5 {eu_flags_r} 5
|
||||
6 BIU_Strobe 6 00,ACC 6 DPTR
|
||||
7 IP 7 IP 7 Opcode Immediate[15:0]
|
||||
8+ 16'h0000
|
||||
|
||||
|
||||
EU Opcodes
|
||||
-----------
|
||||
0x1 - JUMP
|
||||
----------------
|
||||
Bits[31:28] : 0x1
|
||||
Bits[27:24] : CALL 1=Push next IP address to call stack
|
||||
Bits[22:20] : Jump Source:
|
||||
0x0=Immediate[12:0]
|
||||
0x1={4'h0 & code_byte} -- For initial Jump
|
||||
0x2={immediate[xx:0] & code_byte[3:0]} -- Addressing modes
|
||||
0x3=Return to CALL stored IP address -- CALL Return
|
||||
0x4={ 7'h00 , BIU_RETURN_DATA[2:0] } -- Bit Mask decoding table
|
||||
|
||||
|
||||
Bits[19:16] : Jump Condition:
|
||||
0x0=Unconditional
|
||||
0x1=Last_ALU_Result!=0
|
||||
0x2=Last_ALU_Result==0
|
||||
Bits[12:0] : Immediate[12:0]
|
||||
|
||||
|
||||
0x2 - ADD
|
||||
0x3 - XOR
|
||||
0x4 - OR
|
||||
0x5 - AND
|
||||
0x6 - Byte swap eu_operand0
|
||||
0x7 - Shift Right based on type: { immediate[0] , eu_operand0[7:0] }
|
||||
Immedaite = 0 = Eight bit - shift in op0[0],
|
||||
1 = Eight bit - shift in PSW_carry
|
||||
2 = Sixteen bit - shift in eu_add_carry16
|
||||
|
||||
|
||||
|
||||
# Reset the CPU
|
||||
p 00 00000 00001 0001
|
||||
p 01 00000 00001 0000
|
417
MCL51/Core/biu.v
417
MCL51/Core/biu.v
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// File Name : biu.v
|
||||
// Used on :
|
||||
// Author : MicroCore Labs
|
||||
// Author : Ted Fried, MicroCore Labs
|
||||
// Creation : 3/13/16
|
||||
// Code Type : Synthesizable
|
||||
//
|
||||
|
@ -22,38 +22,59 @@
|
|||
//
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
//
|
||||
// Copyright (c) 2020 Ted Fried
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
module biu
|
||||
(
|
||||
input CORE_CLK, // Core Signals
|
||||
input RST_n,
|
||||
input CORE_CLK, // Core Signals
|
||||
input RST_n,
|
||||
|
||||
|
||||
input UART_RX, // Peripheral IOs
|
||||
output UART_TX,
|
||||
output SPEAKER,
|
||||
|
||||
input UART_RX, // Peripheral IOs
|
||||
output UART_TX,
|
||||
output SPEAKER,
|
||||
|
||||
|
||||
input [7:0] EU_BIU_STROBE, // EU to BIU Signals
|
||||
input [7:0] EU_BIU_DATAOUT,
|
||||
input [15:0] EU_REGISTER_R3,
|
||||
input [15:0] EU_REGISTER_IP,
|
||||
|
||||
|
||||
output [7:0] BIU_SFR_ACC, // BIU to EU Signals
|
||||
output [15:0] BIU_SFR_DPTR,
|
||||
output [7:0] BIU_SFR_SP,
|
||||
output [7:0] BIU_SFR_PSW,
|
||||
output [7:0] BIU_RETURN_DATA,
|
||||
output BIU_INTERRUPT,
|
||||
|
||||
input [7:0] EU_BIU_STROBE, // EU to BIU Signals
|
||||
input [7:0] EU_BIU_DATAOUT,
|
||||
input [15:0] EU_REGISTER_R3,
|
||||
input [15:0] EU_REGISTER_IP,
|
||||
|
||||
|
||||
output [7:0] BIU_SFR_ACC, // BIU to EU Signals
|
||||
output [15:0] BIU_SFR_DPTR,
|
||||
output [7:0] BIU_SFR_SP,
|
||||
output [7:0] BIU_SFR_PSW,
|
||||
output [7:0] BIU_RETURN_DATA,
|
||||
output BIU_INTERRUPT,
|
||||
|
||||
output RESET_OUT
|
||||
|
||||
output RESET_OUT
|
||||
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// Internal Signals
|
||||
|
||||
|
@ -64,7 +85,7 @@ wire biu_int2;
|
|||
wire biu_int3;
|
||||
wire biu_sfr_select;
|
||||
wire acc_parity;
|
||||
wire biu_timer_wr_strobe;
|
||||
wire biu_timer_wr_strobe;
|
||||
wire biu_uart_rd_strobe;
|
||||
wire biu_uart_wr_strobe;
|
||||
wire loader_wr;
|
||||
|
@ -85,8 +106,8 @@ wire [7:0] biu_program_data;
|
|||
wire [2:0] eu_biu_strobe_mode;
|
||||
wire [2:0] eu_biu_strobe_int;
|
||||
wire [7:0] biu_ram_dataout;
|
||||
wire [7:0] biu_timer_dataout;
|
||||
wire [7:0] biu_uart_dataout;
|
||||
wire [7:0] biu_timer_dataout;
|
||||
wire [7:0] biu_uart_dataout;
|
||||
wire [15:0] loader_addr_int;
|
||||
wire [7:0] loader_data_int;
|
||||
|
||||
|
@ -96,56 +117,56 @@ wire [7:0] loader_data_int;
|
|||
//
|
||||
// User Program ROM. 4Kx8
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
/* Program ROM without interface to the UART Loader
|
||||
biu_rom BIU_4Kx8
|
||||
biu_rom BIU_4Kx8
|
||||
(
|
||||
.Reset (1'b0),
|
||||
.OutClockEn (1'b1),
|
||||
.OutClock (CORE_CLK),
|
||||
.Address (EU_REGISTER_IP[11:0]),
|
||||
.Q (biu_program_data)
|
||||
.Reset (1'b0),
|
||||
.OutClockEn (1'b1),
|
||||
.OutClock (CORE_CLK),
|
||||
.Address (EU_REGISTER_IP[11:0]),
|
||||
.Q (biu_program_data)
|
||||
);
|
||||
*/
|
||||
|
||||
// For Lattice XO2 Series FPGAs
|
||||
biu_rom_dp BIU_4Kx8
|
||||
biu_rom_dp BIU_4Kx8
|
||||
(
|
||||
.ResetA (1'b0),
|
||||
.ClockEnA (1'b1),
|
||||
.ClockA (CORE_CLK),
|
||||
.WrA (1'b0),
|
||||
.AddressA (EU_REGISTER_IP[11:0]),
|
||||
.DataInA (8'h00),
|
||||
.QA (biu_program_data),
|
||||
.ResetA (1'b0),
|
||||
.ClockEnA (1'b1),
|
||||
.ClockA (CORE_CLK),
|
||||
.WrA (1'b0),
|
||||
.AddressA (EU_REGISTER_IP[11:0]),
|
||||
.DataInA (8'h00),
|
||||
.QA (biu_program_data),
|
||||
|
||||
.ResetB (1'b0),
|
||||
.ClockEnB (1'b1),
|
||||
.ClockB (CORE_CLK),
|
||||
.WrB (loader_wr),
|
||||
.AddressB (loader_addr_int[11:0]),
|
||||
.DataInB (loader_data_int),
|
||||
.QB ( )
|
||||
.ResetB (1'b0),
|
||||
.ClockEnB (1'b1),
|
||||
.ClockB (CORE_CLK),
|
||||
.WrB (loader_wr),
|
||||
.AddressB (loader_addr_int[11:0]),
|
||||
.DataInB (loader_data_int),
|
||||
.QB ( )
|
||||
);
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// User Data RAM. 512x8
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// For Lattice XO2 Series FPGAs
|
||||
biu_ram BIU_512x8
|
||||
biu_ram BIU_512x8
|
||||
(
|
||||
.Reset (1'b0),
|
||||
.ClockEn (1'b1),
|
||||
.Clock (CORE_CLK),
|
||||
.Address (eu_register_r3_d1[8:0]),
|
||||
.Data (EU_BIU_DATAOUT),
|
||||
.Q (biu_ram_dataout),
|
||||
.WE (biu_ram_wr)
|
||||
.Reset (1'b0),
|
||||
.ClockEn (1'b1),
|
||||
.Clock (CORE_CLK),
|
||||
.Address (eu_register_r3_d1[8:0]),
|
||||
.Data (EU_BIU_DATAOUT),
|
||||
.Q (biu_ram_dataout),
|
||||
.WE (biu_ram_wr)
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
@ -160,12 +181,12 @@ biu_ram BIU_512x8
|
|||
assign BIU_SFR_ACC = biu_sfr_acc_int;
|
||||
assign BIU_SFR_DPTR = { biu_sfr_dph_int , biu_sfr_dpl_int };
|
||||
assign BIU_SFR_SP = biu_sfr_sp_int;
|
||||
assign BIU_SFR_PSW = { biu_sfr_psw_int[7:1] , acc_parity };
|
||||
assign BIU_SFR_PSW = { biu_sfr_psw_int[7:1] , acc_parity };
|
||||
|
||||
|
||||
assign BIU_RETURN_DATA = (eu_biu_strobe_mode==2'h0) ? biu_program_data :
|
||||
(biu_sfr_select==1'b1) ? biu_sfr_dataout :
|
||||
biu_ram_dataout ;
|
||||
assign BIU_RETURN_DATA = (eu_biu_strobe_mode==2'h0) ? biu_program_data :
|
||||
(biu_sfr_select==1'b1) ? biu_sfr_dataout :
|
||||
biu_ram_dataout ;
|
||||
|
||||
|
||||
// Parity for the Accumulator
|
||||
|
@ -174,8 +195,8 @@ assign acc_parity = (biu_sfr_acc_int[0]^biu_sfr_acc_int[1]^biu_sfr_acc_int[2]^bi
|
|||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// EU strobes to request BIU processing.
|
||||
assign eu_biu_strobe_mode[2:0] = EU_BIU_STROBE[6:4];
|
||||
assign eu_biu_strobe_int[2:0] = EU_BIU_STROBE[2:0];
|
||||
|
@ -183,7 +204,7 @@ assign eu_biu_strobe_int[2:0] = EU_BIU_STROBE[2:0];
|
|||
|
||||
|
||||
// Select the SFR range if the address is 0x0080 to 0x00FF and addressing mode is Direct
|
||||
assign biu_sfr_select = ( eu_register_r3_d1[15:7]==9'b0000_0000_1 && eu_biu_strobe_mode[1:0]==3'h1) ? 1'b1 : 1'b0;
|
||||
assign biu_sfr_select = ( eu_register_r3_d1[15:7]==9'b0000_0000_1 && eu_biu_strobe_mode[1:0]==3'h1) ? 1'b1 : 1'b0;
|
||||
|
||||
|
||||
// Decode the write enable to the RAM block
|
||||
|
@ -191,41 +212,41 @@ assign biu_ram_wr = (biu_sfr_select==1'b0 && eu_biu_strobe_int==3'h1) ? 1'b1 : 1
|
|||
|
||||
|
||||
// Mux the SFR data outputs
|
||||
assign biu_sfr_dataout = (eu_register_r3_d1[7:0]==8'h81) ? biu_sfr_sp_int :
|
||||
(eu_register_r3_d1[7:0]==8'h82) ? biu_sfr_dpl_int :
|
||||
(eu_register_r3_d1[7:0]==8'h83) ? biu_sfr_dph_int :
|
||||
(eu_register_r3_d1[7:0]==8'hA8) ? biu_sfr_ie_int :
|
||||
(eu_register_r3_d1[7:0]==8'hA9) ? biu_sfr_is_int :
|
||||
assign biu_sfr_dataout = (eu_register_r3_d1[7:0]==8'h81) ? biu_sfr_sp_int :
|
||||
(eu_register_r3_d1[7:0]==8'h82) ? biu_sfr_dpl_int :
|
||||
(eu_register_r3_d1[7:0]==8'h83) ? biu_sfr_dph_int :
|
||||
(eu_register_r3_d1[7:0]==8'hA8) ? biu_sfr_ie_int :
|
||||
(eu_register_r3_d1[7:0]==8'hA9) ? biu_sfr_is_int :
|
||||
(eu_register_r3_d1[7:0]==8'hC0) ? biu_sfr_pxy_din :
|
||||
(eu_register_r3_d1[7:0]==8'hD0) ? biu_sfr_psw_int :
|
||||
(eu_register_r3_d1[7:0]==8'hD0) ? biu_sfr_psw_int :
|
||||
(eu_register_r3_d1[7:0]==8'hE0) ? biu_sfr_acc_int :
|
||||
(eu_register_r3_d1[7:0]==8'hF0) ? biu_sfr_b_int :
|
||||
8'hEE ;
|
||||
8'hEE ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Simple fixed priority interrupt controller
|
||||
// biu_sfr_ie_int[7] is the global_intr_enable
|
||||
// biu_sfr_is_int[3:0] contains the interrupt source
|
||||
// Interrupt 2 = Timer Interrupt Vector at address 0x4
|
||||
// 3 = UART-RX Interrupt Vector at address 0x6
|
||||
// Interrupt 2 = Timer Interrupt Vector at address 0x4
|
||||
// 3 = UART-RX Interrupt Vector at address 0x6
|
||||
//
|
||||
assign BIU_INTERRUPT = (core_interrupt_disable==1'b0 && biu_sfr_ie_int[7]==1'b1 && biu_int2==1'b1) ? 1'b1 :
|
||||
(core_interrupt_disable==1'b0 && biu_sfr_ie_int[7]==1'b1 && biu_int3==1'b1) ? 1'b1 : 1'b0;
|
||||
// (core_interrupt_disable==1'b0 && biu_sfr_ie_int[7]==1'b1 && biu_int4==1'b1) ? 1'b1 :
|
||||
// 1'b0 ;
|
||||
|
||||
// 1'b0 ;
|
||||
|
||||
assign biu_sfr_is_int[7:4] = 4'h0;
|
||||
assign biu_sfr_is_int[3:0] = (biu_int2==1'b1) ? 4'h2 :
|
||||
(biu_int3==1'b1) ? 4'h3 : 4'hF;
|
||||
// 4'h4 ;
|
||||
|
||||
|
||||
|
||||
// 4'h4 ;
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// BIU Controller
|
||||
|
@ -238,89 +259,89 @@ begin : BIU_CONTROLLER
|
|||
|
||||
if (RST_n==1'b0)
|
||||
begin
|
||||
biu_sfr_dpl_int <= 'h0;
|
||||
biu_sfr_dph_int <= 'h0;
|
||||
biu_sfr_ie_int <= 'h0;
|
||||
biu_sfr_psw_int <= 'h0;
|
||||
biu_sfr_acc_int <= 'h0;
|
||||
biu_sfr_b_int <= 8'h00;
|
||||
biu_sfr_sp_int <= 'h07;
|
||||
eu_register_r3_d1 <= 'h0;
|
||||
biu_pxy_rd <= 'h0;
|
||||
biu_pxy_wr <= 'h0;
|
||||
biu_sfr_pxy_addr <= 'h0;
|
||||
biu_sfr_pxy_dout <= 'h0;
|
||||
core_interrupt_disable <= 'h0;
|
||||
biu_sfr_dpl_int <= 'h0;
|
||||
biu_sfr_dph_int <= 'h0;
|
||||
biu_sfr_ie_int <= 'h0;
|
||||
biu_sfr_psw_int <= 'h0;
|
||||
biu_sfr_acc_int <= 'h0;
|
||||
biu_sfr_b_int <= 8'h00;
|
||||
biu_sfr_sp_int <= 'h07;
|
||||
eu_register_r3_d1 <= 'h0;
|
||||
biu_pxy_rd <= 'h0;
|
||||
biu_pxy_wr <= 'h0;
|
||||
biu_sfr_pxy_addr <= 'h0;
|
||||
biu_sfr_pxy_dout <= 'h0;
|
||||
core_interrupt_disable <= 'h0;
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
|
||||
eu_register_r3_d1 <= EU_REGISTER_R3;
|
||||
|
||||
if (eu_biu_strobe_int==3'h3)
|
||||
begin
|
||||
core_interrupt_disable <= 1'b1;
|
||||
end
|
||||
|
||||
if (eu_biu_strobe_int==3'h4)
|
||||
begin
|
||||
core_interrupt_disable <= 1'b0;
|
||||
end
|
||||
|
||||
|
||||
|
||||
// Writes to SFR's
|
||||
if (biu_sfr_select==1'b1 && eu_biu_strobe_int==3'h1)
|
||||
begin
|
||||
case (eu_register_r3_d1[7:0]) // synthesis parallel_case
|
||||
|
||||
8'h81 : biu_sfr_sp_int <= EU_BIU_DATAOUT[7:0];
|
||||
8'h82 : biu_sfr_dpl_int <= EU_BIU_DATAOUT[7:0];
|
||||
8'h83 : biu_sfr_dph_int <= EU_BIU_DATAOUT[7:0];
|
||||
8'hA8 : biu_sfr_ie_int <= EU_BIU_DATAOUT[7:0];
|
||||
8'hD0 : biu_sfr_psw_int <= EU_BIU_DATAOUT[7:0];
|
||||
8'hE0 : biu_sfr_acc_int <= EU_BIU_DATAOUT[7:0];
|
||||
8'hF0 : biu_sfr_b_int <= EU_BIU_DATAOUT[7:0];
|
||||
|
||||
// Proxy Addressing Registers
|
||||
8'hC1 : biu_sfr_pxy_dout <= EU_BIU_DATAOUT[7:0];
|
||||
8'hC2 : biu_sfr_pxy_addr <= EU_BIU_DATAOUT[7:0];
|
||||
|
||||
default : ;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// Assert the write strobe to the proxy addressed peripherals
|
||||
if (biu_sfr_select==1'b1 && eu_biu_strobe_int==3'h1 && eu_register_r3_d1[7:0]==8'hC1)
|
||||
begin
|
||||
biu_pxy_wr <= 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
biu_pxy_wr <= 1'b0;
|
||||
end
|
||||
|
||||
|
||||
// Assert the read strobe to the proxy addressed peripherals
|
||||
if (biu_sfr_select==1'b1 && eu_biu_strobe_int==3'h1 && eu_register_r3_d1[7:0]==8'hC2)
|
||||
begin
|
||||
biu_pxy_rd <= 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
biu_pxy_rd <= 1'b0;
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
if (eu_biu_strobe_int==3'h3)
|
||||
begin
|
||||
core_interrupt_disable <= 1'b1;
|
||||
end
|
||||
|
||||
if (eu_biu_strobe_int==3'h4)
|
||||
begin
|
||||
core_interrupt_disable <= 1'b0;
|
||||
end
|
||||
|
||||
|
||||
|
||||
// Writes to SFR's
|
||||
if (biu_sfr_select==1'b1 && eu_biu_strobe_int==3'h1)
|
||||
begin
|
||||
case (eu_register_r3_d1[7:0]) // synthesis parallel_case
|
||||
|
||||
8'h81 : biu_sfr_sp_int <= EU_BIU_DATAOUT[7:0];
|
||||
8'h82 : biu_sfr_dpl_int <= EU_BIU_DATAOUT[7:0];
|
||||
8'h83 : biu_sfr_dph_int <= EU_BIU_DATAOUT[7:0];
|
||||
8'hA8 : biu_sfr_ie_int <= EU_BIU_DATAOUT[7:0];
|
||||
8'hD0 : biu_sfr_psw_int <= EU_BIU_DATAOUT[7:0];
|
||||
8'hE0 : biu_sfr_acc_int <= EU_BIU_DATAOUT[7:0];
|
||||
8'hF0 : biu_sfr_b_int <= EU_BIU_DATAOUT[7:0];
|
||||
|
||||
// Proxy Addressing Registers
|
||||
8'hC1 : biu_sfr_pxy_dout <= EU_BIU_DATAOUT[7:0];
|
||||
8'hC2 : biu_sfr_pxy_addr <= EU_BIU_DATAOUT[7:0];
|
||||
|
||||
default : ;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// Assert the write strobe to the proxy addressed peripherals
|
||||
if (biu_sfr_select==1'b1 && eu_biu_strobe_int==3'h1 && eu_register_r3_d1[7:0]==8'hC1)
|
||||
begin
|
||||
biu_pxy_wr <= 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
biu_pxy_wr <= 1'b0;
|
||||
end
|
||||
|
||||
|
||||
// Assert the read strobe to the proxy addressed peripherals
|
||||
if (biu_sfr_select==1'b1 && eu_biu_strobe_int==3'h1 && eu_register_r3_d1[7:0]==8'hC2)
|
||||
begin
|
||||
biu_pxy_rd <= 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
biu_pxy_rd <= 1'b0;
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
|
@ -338,14 +359,14 @@ end
|
|||
//
|
||||
|
||||
// Steer the peripheral read data
|
||||
assign biu_sfr_pxy_din = (biu_sfr_pxy_addr[7:4]==4'h0) ? biu_timer_dataout :
|
||||
(biu_sfr_pxy_addr[7:4]==4'h1) ? biu_uart_dataout :
|
||||
8'hEE ;
|
||||
|
||||
assign biu_sfr_pxy_din = (biu_sfr_pxy_addr[7:4]==4'h0) ? biu_timer_dataout :
|
||||
(biu_sfr_pxy_addr[7:4]==4'h1) ? biu_uart_dataout :
|
||||
8'hEE ;
|
||||
|
||||
// Gate the peripheral read and write strobes
|
||||
assign biu_timer_wr_strobe = (biu_sfr_pxy_addr[7:4]==4'h0) ? biu_pxy_wr : 1'b0;
|
||||
assign biu_uart_wr_strobe = (biu_sfr_pxy_addr[7:4]==4'h1) ? biu_pxy_wr : 1'b0;
|
||||
assign biu_uart_rd_strobe = (biu_sfr_pxy_addr[7:4]==4'h1) ? biu_pxy_rd : 1'b0;
|
||||
assign biu_timer_wr_strobe = (biu_sfr_pxy_addr[7:4]==4'h0) ? biu_pxy_wr : 1'b0;
|
||||
assign biu_uart_wr_strobe = (biu_sfr_pxy_addr[7:4]==4'h1) ? biu_pxy_wr : 1'b0;
|
||||
assign biu_uart_rd_strobe = (biu_sfr_pxy_addr[7:4]==4'h1) ? biu_pxy_rd : 1'b0;
|
||||
|
||||
|
||||
|
||||
|
@ -357,49 +378,49 @@ assign biu_uart_rd_strobe = (biu_sfr_pxy_addr[7:4]==4'h1) ? biu_pxy_rd : 1'b0;
|
|||
// Timer-0 = Frequency generator
|
||||
// Timer-1 = Pulse generator
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
timer BIU_TIMER
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
timer BIU_TIMER
|
||||
(
|
||||
.CORE_CLK (CORE_CLK),
|
||||
.RST_n (RST_n),
|
||||
.ADDRESS (biu_sfr_pxy_addr[3:0]),
|
||||
.DATA_IN (biu_sfr_pxy_dout),
|
||||
.DATA_OUT (biu_timer_dataout),
|
||||
.STROBE_WR (biu_timer_wr_strobe),
|
||||
.TIMER0_OUT (SPEAKER),
|
||||
.TIMER1_OUT (biu_int2)
|
||||
.CORE_CLK (CORE_CLK),
|
||||
.RST_n (RST_n),
|
||||
.ADDRESS (biu_sfr_pxy_addr[3:0]),
|
||||
.DATA_IN (biu_sfr_pxy_dout),
|
||||
.DATA_OUT (biu_timer_dataout),
|
||||
.STROBE_WR (biu_timer_wr_strobe),
|
||||
.TIMER0_OUT (SPEAKER),
|
||||
.TIMER1_OUT (biu_int2)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// UART - Fixed 9600 baud
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
uart_and_loader BIU_UART
|
||||
uart_and_loader BIU_UART
|
||||
(
|
||||
.CLK (CORE_CLK),
|
||||
.RST_n (RST_n),
|
||||
.ADDRESS (biu_sfr_pxy_addr[1:0]),
|
||||
.DATA_IN (biu_sfr_pxy_dout),
|
||||
.DATA_OUT (biu_uart_dataout),
|
||||
.STROBE_RD (biu_uart_rd_strobe),
|
||||
.STROBE_WR (biu_uart_wr_strobe),
|
||||
.UART_RX (UART_RX),
|
||||
.UART_TX (UART_TX),
|
||||
.UART_INT (biu_int3),
|
||||
.CLK (CORE_CLK),
|
||||
.RST_n (RST_n),
|
||||
.ADDRESS (biu_sfr_pxy_addr[1:0]),
|
||||
.DATA_IN (biu_sfr_pxy_dout),
|
||||
.DATA_OUT (biu_uart_dataout),
|
||||
.STROBE_RD (biu_uart_rd_strobe),
|
||||
.STROBE_WR (biu_uart_wr_strobe),
|
||||
.UART_RX (UART_RX),
|
||||
.UART_TX (UART_TX),
|
||||
.UART_INT (biu_int3),
|
||||
|
||||
.LOADER_ADDR (loader_addr_int ),
|
||||
.LOADER_DATA (loader_data_int ),
|
||||
.LOADER_WR (loader_wr ),
|
||||
.RESET_OUT (RESET_OUT )
|
||||
|
||||
.LOADER_ADDR (loader_addr_int ),
|
||||
.LOADER_DATA (loader_data_int ),
|
||||
.LOADER_WR (loader_wr ),
|
||||
.RESET_OUT (RESET_OUT )
|
||||
|
||||
);
|
||||
|
||||
|
||||
|
||||
endmodule // biu.v
|
||||
|
||||
|
||||
|
||||
|
296
MCL51/Core/eu.v
296
MCL51/Core/eu.v
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// File Name : eu.v
|
||||
// Used on : MCL51
|
||||
// Author : MicroCore Labs
|
||||
// Author : Ted Fried, MicroCore Labs
|
||||
// Creation : 3/13/2016
|
||||
// Code Type : Synthesizable
|
||||
//
|
||||
|
@ -21,31 +21,53 @@
|
|||
//
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2020 Ted Fried
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
module eu
|
||||
(
|
||||
input CORE_CLK, // Core Clock
|
||||
input RST_n,
|
||||
|
||||
|
||||
output [7:0] EU_BIU_STROBE, // EU to BIU Signals
|
||||
output [7:0] EU_BIU_DATAOUT,
|
||||
output [15:0] EU_REGISTER_R3,
|
||||
output [15:0] EU_REGISTER_IP,
|
||||
|
||||
|
||||
input [7:0] BIU_SFR_ACC, // BIU to EU Signals
|
||||
input [15:0] BIU_SFR_DPTR,
|
||||
input [7:0] BIU_SFR_SP,
|
||||
input [7:0] BIU_SFR_PSW,
|
||||
input [7:0] BIU_RETURN_DATA,
|
||||
input BIU_INTERRUPT
|
||||
input CORE_CLK, // Core Clock
|
||||
input RST_n,
|
||||
|
||||
|
||||
output [7:0] EU_BIU_STROBE, // EU to BIU Signals
|
||||
output [7:0] EU_BIU_DATAOUT,
|
||||
output [15:0] EU_REGISTER_R3,
|
||||
output [15:0] EU_REGISTER_IP,
|
||||
|
||||
|
||||
input [7:0] BIU_SFR_ACC, // BIU to EU Signals
|
||||
input [15:0] BIU_SFR_DPTR,
|
||||
input [7:0] BIU_SFR_SP,
|
||||
input [7:0] BIU_SFR_PSW,
|
||||
input [7:0] BIU_RETURN_DATA,
|
||||
input BIU_INTERRUPT
|
||||
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// Internal Signals
|
||||
|
||||
|
@ -94,29 +116,29 @@ wire [15:0] eu_flags_r;
|
|||
//
|
||||
// EU Microcode ROM. 1Kx32
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
/*
|
||||
// For Lattice XO2 FPGAs
|
||||
eu_rom EU_1Kx32
|
||||
eu_rom EU_1Kx32
|
||||
(
|
||||
.Reset (1'b0),
|
||||
.OutClockEn (1'b1),
|
||||
.OutClock (CORE_CLK),
|
||||
.Address (eu_rom_address[9:0]),
|
||||
.Q (eu_rom_data)
|
||||
.Reset (1'b0),
|
||||
.OutClockEn (1'b1),
|
||||
.OutClock (CORE_CLK),
|
||||
.Address (eu_rom_address[9:0]),
|
||||
.Q (eu_rom_data)
|
||||
);
|
||||
*/
|
||||
|
||||
// For Xilinx Artix FPGAs
|
||||
eu_rom EU_1Kx32
|
||||
eu_rom EU_1Kx32
|
||||
(
|
||||
.clka (CORE_CLK),
|
||||
.addra (eu_rom_address[9:0]),
|
||||
.douta (eu_rom_data)
|
||||
.clka (CORE_CLK),
|
||||
.addra (eu_rom_address[9:0]),
|
||||
.douta (eu_rom_data)
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -127,72 +149,72 @@ eu_rom EU_1Kx32
|
|||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
assign EU_BIU_STROBE = eu_biu_strobe;
|
||||
assign EU_BIU_DATAOUT = eu_biu_dataout;
|
||||
assign EU_REGISTER_R3 = eu_register_r3;
|
||||
assign EU_REGISTER_IP = eu_register_ip;
|
||||
assign EU_BIU_STROBE = eu_biu_strobe;
|
||||
assign EU_BIU_DATAOUT = eu_biu_dataout;
|
||||
assign EU_REGISTER_R3 = eu_register_r3;
|
||||
assign EU_REGISTER_IP = eu_register_ip;
|
||||
|
||||
|
||||
// EU ROM opcode decoder
|
||||
assign eu_opcode_type = eu_rom_data[30:28];
|
||||
assign eu_opcode_dst_sel = eu_rom_data[26:24];
|
||||
assign eu_opcode_op0_sel = eu_rom_data[23:20];
|
||||
assign eu_opcode_op1_sel = eu_rom_data[18:16];
|
||||
assign eu_opcode_type = eu_rom_data[30:28];
|
||||
assign eu_opcode_dst_sel = eu_rom_data[26:24];
|
||||
assign eu_opcode_op0_sel = eu_rom_data[23:20];
|
||||
assign eu_opcode_op1_sel = eu_rom_data[18:16];
|
||||
assign eu_opcode_immediate = eu_rom_data[15:0];
|
||||
|
||||
assign eu_opcode_jump_call = eu_rom_data[24];
|
||||
assign eu_opcode_jump_src = eu_rom_data[22:20];
|
||||
assign eu_opcode_jump_cond = eu_rom_data[18:16];
|
||||
assign eu_opcode_jump_call = eu_rom_data[24];
|
||||
assign eu_opcode_jump_src = eu_rom_data[22:20];
|
||||
assign eu_opcode_jump_cond = eu_rom_data[18:16];
|
||||
|
||||
|
||||
|
||||
assign eu_operand0 = (eu_opcode_op0_sel==4'h0) ? eu_register_r0 :
|
||||
(eu_opcode_op0_sel==4'h1) ? eu_register_r1 :
|
||||
(eu_opcode_op0_sel==4'h2) ? eu_register_r2 :
|
||||
(eu_opcode_op0_sel==4'h3) ? eu_register_r3 :
|
||||
assign eu_operand0 = (eu_opcode_op0_sel==4'h0) ? eu_register_r0 :
|
||||
(eu_opcode_op0_sel==4'h1) ? eu_register_r1 :
|
||||
(eu_opcode_op0_sel==4'h2) ? eu_register_r2 :
|
||||
(eu_opcode_op0_sel==4'h3) ? eu_register_r3 :
|
||||
(eu_opcode_op0_sel==4'h4) ? { 8'h00 , BIU_RETURN_DATA } :
|
||||
(eu_opcode_op0_sel==4'h5) ? { eu_flags_r[15:0] } :
|
||||
(eu_opcode_op0_sel==4'h5) ? { eu_flags_r[15:0] } :
|
||||
(eu_opcode_op0_sel==4'h6) ? { 8'h00 , BIU_SFR_ACC } :
|
||||
(eu_opcode_op0_sel==4'h7) ? eu_register_ip :
|
||||
16'h0000 ;
|
||||
(eu_opcode_op0_sel==4'h7) ? eu_register_ip :
|
||||
16'h0000 ;
|
||||
|
||||
assign eu_operand1 = (eu_opcode_op1_sel==3'h0) ? eu_register_r0 :
|
||||
(eu_opcode_op1_sel==3'h1) ? eu_register_r1 :
|
||||
(eu_opcode_op1_sel==3'h2) ? eu_register_r2 :
|
||||
(eu_opcode_op1_sel==3'h3) ? eu_register_r3 :
|
||||
(eu_opcode_op1_sel==3'h4) ? { 8'h00 , BIU_SFR_SP } :
|
||||
//(eu_opcode_op1_sel==3'h5) ? eu_alu_last_result :
|
||||
(eu_opcode_op1_sel==3'h6) ? BIU_SFR_DPTR :
|
||||
eu_opcode_immediate ;
|
||||
assign eu_operand1 = (eu_opcode_op1_sel==3'h0) ? eu_register_r0 :
|
||||
(eu_opcode_op1_sel==3'h1) ? eu_register_r1 :
|
||||
(eu_opcode_op1_sel==3'h2) ? eu_register_r2 :
|
||||
(eu_opcode_op1_sel==3'h3) ? eu_register_r3 :
|
||||
(eu_opcode_op1_sel==3'h4) ? { 8'h00 , BIU_SFR_SP } :
|
||||
//(eu_opcode_op1_sel==3'h5) ? eu_alu_last_result :
|
||||
(eu_opcode_op1_sel==3'h6) ? BIU_SFR_DPTR :
|
||||
eu_opcode_immediate ;
|
||||
|
||||
|
||||
|
||||
// JUMP condition codes
|
||||
assign eu_jump_gate = (eu_opcode_jump_cond==4'h0) ? 1'b1 : // unconditional jump
|
||||
(eu_opcode_jump_cond==4'h1 && eu_alu_last_result!=16'h0) ? 1'b1 :
|
||||
(eu_opcode_jump_cond==4'h2 && eu_alu_last_result==16'h0) ? 1'b1 :
|
||||
1'b0 ;
|
||||
1'b0 ;
|
||||
|
||||
|
||||
|
||||
|
||||
// ** Flags must be written to the PSW through the BIU
|
||||
|
||||
assign eu_flags_r[15] = eu_add_carry;
|
||||
assign eu_flags_r[14] = eu_add_aux_carry;
|
||||
|
||||
assign eu_flags_r[15] = eu_add_carry;
|
||||
assign eu_flags_r[14] = eu_add_aux_carry;
|
||||
assign eu_flags_r[13] = eu_add_carry16;
|
||||
//assign eu_flags_r[12] =
|
||||
//assign eu_flags_r[11] =
|
||||
assign eu_flags_r[10] = eu_add_overflow;
|
||||
//assign eu_flags_r[9] =
|
||||
assign eu_flags_r[8] = BIU_INTERRUPT;
|
||||
//assign eu_flags_r[12] =
|
||||
//assign eu_flags_r[11] =
|
||||
assign eu_flags_r[10] = eu_add_overflow;
|
||||
//assign eu_flags_r[9] =
|
||||
assign eu_flags_r[8] = BIU_INTERRUPT;
|
||||
|
||||
assign eu_flags_r[7] = BIU_SFR_PSW[7]; // C
|
||||
assign eu_flags_r[6] = BIU_SFR_PSW[6]; // AC
|
||||
assign eu_flags_r[5] = BIU_SFR_PSW[5]; // F0
|
||||
assign eu_flags_r[4] = BIU_SFR_PSW[4]; // RS1
|
||||
assign eu_flags_r[3] = BIU_SFR_PSW[3]; // RS0
|
||||
assign eu_flags_r[2] = BIU_SFR_PSW[2]; // Overflow
|
||||
assign eu_flags_r[1] = BIU_SFR_PSW[1]; // User Defined Flag
|
||||
assign eu_flags_r[0] = BIU_SFR_PSW[0]; // ACC Parity generated in the BIU
|
||||
assign eu_flags_r[7] = BIU_SFR_PSW[7]; // C
|
||||
assign eu_flags_r[6] = BIU_SFR_PSW[6]; // AC
|
||||
assign eu_flags_r[5] = BIU_SFR_PSW[5]; // F0
|
||||
assign eu_flags_r[4] = BIU_SFR_PSW[4]; // RS1
|
||||
assign eu_flags_r[3] = BIU_SFR_PSW[3]; // RS0
|
||||
assign eu_flags_r[2] = BIU_SFR_PSW[2]; // Overflow
|
||||
assign eu_flags_r[1] = BIU_SFR_PSW[1]; // User Defined Flag
|
||||
assign eu_flags_r[0] = BIU_SFR_PSW[0]; // ACC Parity generated in the BIU
|
||||
|
||||
|
||||
|
||||
|
@ -201,13 +223,13 @@ assign eu_flags_r[0] = BIU_SFR_PSW[0]; // ACC Parity generated in the BIU
|
|||
// ------------------------------------------
|
||||
// eu_alu0 = NOP
|
||||
// eu_alu1 = JUMP
|
||||
assign eu_alu2 = adder_out; // ADD
|
||||
assign eu_alu3 = eu_operand0 ^ eu_operand1; // XOR
|
||||
assign eu_alu4 = eu_operand0 | eu_operand1; // OR
|
||||
assign eu_alu5 = eu_operand0 & eu_operand1; // AND
|
||||
assign eu_alu6 = { eu_operand0[7:0] , eu_operand0[15:8] }; // BYTESWAP
|
||||
assign eu_alu7 = (eu_opcode_immediate[1:0]==2'h0) ? { 8'h00 , eu_operand0[0] , eu_operand0[7:1] } : // Rotate in bit[0]
|
||||
(eu_opcode_immediate[1:0]==2'h1) ? { 8'h00 , BIU_SFR_PSW[7] , eu_operand0[7:1] } : // Rotate in Carry bit
|
||||
assign eu_alu2 = adder_out; // ADD
|
||||
assign eu_alu3 = eu_operand0 ^ eu_operand1; // XOR
|
||||
assign eu_alu4 = eu_operand0 | eu_operand1; // OR
|
||||
assign eu_alu5 = eu_operand0 & eu_operand1; // AND
|
||||
assign eu_alu6 = { eu_operand0[7:0] , eu_operand0[15:8] }; // BYTESWAP
|
||||
assign eu_alu7 = (eu_opcode_immediate[1:0]==2'h0) ? { 8'h00 , eu_operand0[0] , eu_operand0[7:1] } : // Rotate in bit[0]
|
||||
(eu_opcode_immediate[1:0]==2'h1) ? { 8'h00 , BIU_SFR_PSW[7] , eu_operand0[7:1] } : // Rotate in Carry bit
|
||||
{ eu_add_carry16 , eu_operand0[15:1] } ; // 16-bit shift-right
|
||||
|
||||
|
||||
|
@ -220,7 +242,7 @@ assign eu_alu_out = (eu_opcode_type==3'h2) ? eu_alu2 :
|
|||
(eu_opcode_type==3'h7) ? eu_alu7 :
|
||||
16'hEEEE;
|
||||
|
||||
|
||||
|
||||
|
||||
// Generate 16-bit full adder for the EU
|
||||
assign carry[0] = 1'b0;
|
||||
|
@ -228,17 +250,17 @@ genvar i;
|
|||
generate
|
||||
for (i=0; i < 16; i=i+1)
|
||||
begin : GEN_ADDER
|
||||
assign adder_out[i] = eu_operand0[i] ^ eu_operand1[i] ^ carry[i];
|
||||
assign carry[i+1] = (eu_operand0[i] & eu_operand1[i]) | (eu_operand0[i] & carry[i]) | (eu_operand1[i] & carry[i]);
|
||||
assign adder_out[i] = eu_operand0[i] ^ eu_operand1[i] ^ carry[i];
|
||||
assign carry[i+1] = (eu_operand0[i] & eu_operand1[i]) | (eu_operand0[i] & carry[i]) | (eu_operand1[i] & carry[i]);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
||||
|
||||
|
||||
assign new_instruction = (eu_rom_address[9:8]==2'b00) ? 1'b1 : 1'b0;
|
||||
assign new_instruction = (eu_rom_address[9:8]==2'b00) ? 1'b1 : 1'b0;
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
//
|
||||
// EU Microsequencer
|
||||
|
@ -259,7 +281,7 @@ begin : EU_MICROSEQUENCER
|
|||
eu_register_r1 <= 'h0;
|
||||
eu_register_r2 <= 'h0;
|
||||
eu_register_r3 <= 'h0;
|
||||
eu_register_ip <= 16'hFFFF; // User Program code starts at 0x0000 after reset. Main loop does initial increment.
|
||||
eu_register_ip <= 16'hFFFF; // User Program code starts at 0x0000 after reset. Main loop does initial increment.
|
||||
eu_biu_strobe <= 'h0;
|
||||
eu_biu_dataout <= 'h0;
|
||||
eu_stall_pipeline <= 'h0;
|
||||
|
@ -270,64 +292,64 @@ begin : EU_MICROSEQUENCER
|
|||
else
|
||||
begin
|
||||
|
||||
|
||||
// Generate and store flags for addition
|
||||
if (eu_stall_pipeline==1'b0 && eu_opcode_type==3'h2)
|
||||
begin
|
||||
eu_add_carry16 <= carry[16];
|
||||
eu_add_carry <= carry[8];
|
||||
eu_add_aux_carry <= carry[4];
|
||||
eu_add_overflow <= carry[8] ^ carry[7];
|
||||
|
||||
// Generate and store flags for addition
|
||||
if (eu_stall_pipeline==1'b0 && eu_opcode_type==3'h2)
|
||||
begin
|
||||
eu_add_carry16 <= carry[16];
|
||||
eu_add_carry <= carry[8];
|
||||
eu_add_aux_carry <= carry[4];
|
||||
eu_add_overflow <= carry[8] ^ carry[7];
|
||||
end
|
||||
|
||||
|
||||
// Register writeback
|
||||
|
||||
// Register writeback
|
||||
if (eu_stall_pipeline==1'b0 && eu_opcode_type!=3'h0 && eu_opcode_type!=3'h1)
|
||||
begin
|
||||
eu_alu_last_result <= eu_alu_out[15:0];
|
||||
case (eu_opcode_dst_sel) // synthesis parallel_case
|
||||
3'h0 : eu_register_r0 <= eu_alu_out[15:0];
|
||||
3'h1 : eu_register_r1 <= eu_alu_out[15:0];
|
||||
3'h2 : eu_register_r2 <= eu_alu_out[15:0];
|
||||
3'h3 : eu_register_r3 <= eu_alu_out[15:0];
|
||||
3'h4 : eu_biu_dataout <= eu_alu_out[7:0];
|
||||
//3'h5 :
|
||||
3'h6 : eu_biu_strobe <= eu_alu_out[7:0];
|
||||
3'h7 : eu_register_ip <= eu_alu_out[15:0];
|
||||
default : ;
|
||||
endcase
|
||||
begin
|
||||
eu_alu_last_result <= eu_alu_out[15:0];
|
||||
case (eu_opcode_dst_sel) // synthesis parallel_case
|
||||
3'h0 : eu_register_r0 <= eu_alu_out[15:0];
|
||||
3'h1 : eu_register_r1 <= eu_alu_out[15:0];
|
||||
3'h2 : eu_register_r2 <= eu_alu_out[15:0];
|
||||
3'h3 : eu_register_r3 <= eu_alu_out[15:0];
|
||||
3'h4 : eu_biu_dataout <= eu_alu_out[7:0];
|
||||
//3'h5 :
|
||||
3'h6 : eu_biu_strobe <= eu_alu_out[7:0];
|
||||
3'h7 : eu_register_ip <= eu_alu_out[15:0];
|
||||
default : ;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// JUMP Opcode
|
||||
if (eu_stall_pipeline==1'b0 && eu_opcode_type==3'h1 && eu_jump_gate==1'b1)
|
||||
begin
|
||||
eu_stall_pipeline <= 1'b1;
|
||||
|
||||
// For subroutine CALLs, store next opcode address
|
||||
if (eu_opcode_jump_call==1'b1)
|
||||
begin
|
||||
eu_calling_address[19:0] <= {eu_calling_address[9:0] , eu_rom_address[9:0] }; // Two deep calling addresses
|
||||
end
|
||||
// JUMP Opcode
|
||||
if (eu_stall_pipeline==1'b0 && eu_opcode_type==3'h1 && eu_jump_gate==1'b1)
|
||||
begin
|
||||
eu_stall_pipeline <= 1'b1;
|
||||
|
||||
// For subroutine CALLs, store next opcode address
|
||||
if (eu_opcode_jump_call==1'b1)
|
||||
begin
|
||||
eu_calling_address[19:0] <= {eu_calling_address[9:0] , eu_rom_address[9:0] }; // Two deep calling addresses
|
||||
end
|
||||
|
||||
case (eu_opcode_jump_src) // synthesis parallel_case
|
||||
3'h0 : eu_rom_address <= eu_opcode_immediate[9:0];
|
||||
3'h1 : eu_rom_address <= { 2'h0 , BIU_RETURN_DATA }; // Initial opcode jump decoding
|
||||
3'h2 : eu_rom_address <= { eu_opcode_immediate[9:4] , eu_register_r0[11:8] }; // EA decoding
|
||||
3'h3 : begin // CALL Return
|
||||
eu_rom_address <= eu_calling_address[9:0];
|
||||
eu_calling_address[9:0] <= eu_calling_address[19:10];
|
||||
end
|
||||
3'h4 : eu_rom_address <= { eu_opcode_immediate[5:0] , BIU_RETURN_DATA[2:0] , 1'b0 }; // Bit Mask decoding table
|
||||
|
||||
default : ;
|
||||
endcase
|
||||
end
|
||||
|
||||
case (eu_opcode_jump_src) // synthesis parallel_case
|
||||
3'h0 : eu_rom_address <= eu_opcode_immediate[9:0];
|
||||
3'h1 : eu_rom_address <= { 2'h0 , BIU_RETURN_DATA }; // Initial opcode jump decoding
|
||||
3'h2 : eu_rom_address <= { eu_opcode_immediate[9:4] , eu_register_r0[11:8] }; // EA decoding
|
||||
3'h3 : begin // CALL Return
|
||||
eu_rom_address <= eu_calling_address[9:0];
|
||||
eu_calling_address[9:0] <= eu_calling_address[19:10];
|
||||
end
|
||||
3'h4 : eu_rom_address <= { eu_opcode_immediate[5:0] , BIU_RETURN_DATA[2:0] , 1'b0 }; // Bit Mask decoding table
|
||||
|
||||
default : ;
|
||||
endcase
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
eu_stall_pipeline <= 1'b0; // Debounce the pipeline stall
|
||||
eu_rom_address <= eu_rom_address + 1'b1;
|
||||
eu_stall_pipeline <= 1'b0; // Debounce the pipeline stall
|
||||
eu_rom_address <= eu_rom_address + 1'b1;
|
||||
end
|
||||
|
||||
end
|
||||
|
|
493
MCL65/MCL65.v
493
MCL65/MCL65.v
|
@ -21,37 +21,58 @@
|
|||
//
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2020 Ted Fried
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
module MCL65
|
||||
(
|
||||
input CORE_CLK, // Microsequencer Core Clock
|
||||
|
||||
input CORE_CLK, // Microsequencer Core Clock
|
||||
|
||||
input CLK0, // 6502 Bus Signals
|
||||
output CLK1,
|
||||
output CLK2,
|
||||
input CLK0, // 6502 Bus Signals
|
||||
output CLK1,
|
||||
output CLK2,
|
||||
|
||||
input RESET_n,
|
||||
input NMI_n,
|
||||
input IRQ_n,
|
||||
input SO,
|
||||
input RESET_n,
|
||||
input NMI_n,
|
||||
input IRQ_n,
|
||||
input SO,
|
||||
|
||||
output SYNC,
|
||||
output RDWR_n,
|
||||
input READY,
|
||||
|
||||
output [15:0] A,
|
||||
inout [7:0] D,
|
||||
|
||||
output DIR0,
|
||||
output DIR1
|
||||
output SYNC,
|
||||
output RDWR_n,
|
||||
input READY,
|
||||
|
||||
output [15:0] A,
|
||||
inout [7:0] D,
|
||||
|
||||
output DIR0,
|
||||
output DIR1
|
||||
|
||||
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// Internal Signals
|
||||
|
||||
|
@ -65,18 +86,18 @@ reg clk0_int_d3 = 'h0;
|
|||
reg clk0_int_d4 = 'h0;
|
||||
reg reset_n_d1 = 'h0;
|
||||
reg reset_n_d2 = 'h0;
|
||||
reg nmi_n_d1 = 'h0;
|
||||
reg nmi_n_d2 = 'h0;
|
||||
reg nmi_n_d3 = 'h0;
|
||||
reg nmi_asserted = 'h0;
|
||||
reg nmi_n_d1 = 'h0;
|
||||
reg nmi_n_d2 = 'h0;
|
||||
reg nmi_n_d3 = 'h0;
|
||||
reg nmi_asserted = 'h0;
|
||||
reg irq_d1 = 'h0;
|
||||
reg irq_d2 = 'h0;
|
||||
reg irq_d3 = 'h0;
|
||||
reg irq_d4 = 'h0;
|
||||
reg irq_gated = 'h0;
|
||||
reg so_n_d1 = 'h0;
|
||||
reg so_n_d2 = 'h0;
|
||||
reg so_n_d3 = 'h0;
|
||||
reg so_n_d1 = 'h0;
|
||||
reg so_n_d2 = 'h0;
|
||||
reg so_n_d3 = 'h0;
|
||||
reg so_asserted = 'h0;
|
||||
reg stall_pipeline = 'h0;
|
||||
reg sync_int_d1 = 'h0;
|
||||
|
@ -85,7 +106,7 @@ reg rdwr_n_int_d2 = 'h0;
|
|||
reg ready_int_d1 = 'h0;
|
||||
reg ready_int_d2 = 'h0;
|
||||
reg ready_int_d3 = 'h0;
|
||||
reg dataout_enable = 'h0;
|
||||
reg dataout_enable = 'h0;
|
||||
wire flag_n;
|
||||
wire flag_v;
|
||||
wire flag_b;
|
||||
|
@ -116,9 +137,9 @@ reg [4:0] system_output = 5'h01;
|
|||
reg [7:0] data_out = 'h0;
|
||||
reg [7:0] data_in_d1 = 'h0;
|
||||
reg [7:0] data_in_d2 = 'h0;
|
||||
reg [7:0] register_flags = 8'h00;
|
||||
reg [15:0] a_out_int = 'h0;
|
||||
reg [7:0] d_out_int = 'h0;
|
||||
reg [7:0] register_flags = 8'h00;
|
||||
reg [15:0] a_out_int = 'h0;
|
||||
reg [7:0] d_out_int = 'h0;
|
||||
wire [15:0] adder_out;
|
||||
wire [16:0] carry;
|
||||
wire [2:0] opcode_type;
|
||||
|
@ -143,13 +164,13 @@ wire [31:0] rom_data;
|
|||
//
|
||||
// 2Kx32 Microcode ROM
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
ROM_2Kx32 microcode_rom
|
||||
ROM_2Kx32 microcode_rom
|
||||
(
|
||||
.clka (CORE_CLK),
|
||||
.addra (rom_address[10:0]),
|
||||
.douta (rom_data)
|
||||
.clka (CORE_CLK),
|
||||
.addra (rom_address[10:0]),
|
||||
.douta (rom_data)
|
||||
);
|
||||
|
||||
|
||||
|
@ -160,106 +181,106 @@ ROM_2Kx32 microcode_rom
|
|||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
assign A = a_out_int;
|
||||
assign D = (dataout_enable==1'b1) ? d_out_int : 8'hZZ;
|
||||
assign A = a_out_int;
|
||||
assign D = (dataout_enable==1'b1) ? d_out_int : 8'hZZ;
|
||||
|
||||
assign DIR0 = dataout_enable;
|
||||
assign DIR1 = dataout_enable;
|
||||
assign DIR0 = dataout_enable;
|
||||
assign DIR1 = dataout_enable;
|
||||
|
||||
assign CLK1 = clk1_out_int;
|
||||
assign CLK2 = clk2_out_int;
|
||||
assign CLK1 = clk1_out_int;
|
||||
assign CLK2 = clk2_out_int;
|
||||
|
||||
|
||||
assign so_debounce = system_output[4];
|
||||
assign nmi_debounce = system_output[3];
|
||||
//assign dataout_enable = system_output[2];
|
||||
assign sync_int = system_output[1];
|
||||
assign rdwr_n_int = system_output[0];
|
||||
assign so_debounce = system_output[4];
|
||||
assign nmi_debounce = system_output[3];
|
||||
//assign dataout_enable = system_output[2];
|
||||
assign sync_int = system_output[1];
|
||||
assign rdwr_n_int = system_output[0];
|
||||
|
||||
assign SYNC = sync_int_d1;
|
||||
assign RDWR_n = rdwr_n_int_d1;
|
||||
assign SYNC = sync_int_d1;
|
||||
assign RDWR_n = rdwr_n_int_d1;
|
||||
|
||||
// Microcode ROM opcode decoder
|
||||
assign opcode_type = rom_data[30:28];
|
||||
assign opcode_dst_sel = rom_data[27:24];
|
||||
assign opcode_op0_sel = rom_data[23:20];
|
||||
assign opcode_op1_sel = rom_data[19:16];
|
||||
assign opcode_immediate = rom_data[15:0];
|
||||
assign opcode_type = rom_data[30:28];
|
||||
assign opcode_dst_sel = rom_data[27:24];
|
||||
assign opcode_op0_sel = rom_data[23:20];
|
||||
assign opcode_op1_sel = rom_data[19:16];
|
||||
assign opcode_immediate = rom_data[15:0];
|
||||
|
||||
assign opcode_jump_call = rom_data[24];
|
||||
assign opcode_jump_src = rom_data[22:20];
|
||||
assign opcode_jump_cond = rom_data[19:16];
|
||||
assign opcode_jump_call = rom_data[24];
|
||||
assign opcode_jump_src = rom_data[22:20];
|
||||
assign opcode_jump_cond = rom_data[19:16];
|
||||
|
||||
|
||||
|
||||
assign operand0 = (opcode_op0_sel==4'h0) ? register_r0 :
|
||||
(opcode_op0_sel==4'h1) ? register_r1 :
|
||||
(opcode_op0_sel==4'h2) ? register_r2 :
|
||||
(opcode_op0_sel==4'h3) ? register_r3 :
|
||||
(opcode_op0_sel==4'h4) ? { 8'h00 , register_a } :
|
||||
(opcode_op0_sel==4'h5) ? { 8'h00 , register_x } :
|
||||
(opcode_op0_sel==4'h6) ? { 8'h00 , register_y } :
|
||||
(opcode_op0_sel==4'h7) ? register_pc :
|
||||
(opcode_op0_sel==4'h8) ? { 8'h01 , register_sp } :
|
||||
(opcode_op0_sel==4'h9) ? { 8'h00 , register_flags } :
|
||||
(opcode_op0_sel==4'hA) ? address_out :
|
||||
(opcode_op0_sel==4'hB) ? { data_in_d2 , data_in_d2 } :
|
||||
(opcode_op0_sel==4'hC) ? system_status :
|
||||
assign operand0 = (opcode_op0_sel==4'h0) ? register_r0 :
|
||||
(opcode_op0_sel==4'h1) ? register_r1 :
|
||||
(opcode_op0_sel==4'h2) ? register_r2 :
|
||||
(opcode_op0_sel==4'h3) ? register_r3 :
|
||||
(opcode_op0_sel==4'h4) ? { 8'h00 , register_a } :
|
||||
(opcode_op0_sel==4'h5) ? { 8'h00 , register_x } :
|
||||
(opcode_op0_sel==4'h6) ? { 8'h00 , register_y } :
|
||||
(opcode_op0_sel==4'h7) ? register_pc :
|
||||
(opcode_op0_sel==4'h8) ? { 8'h01 , register_sp } :
|
||||
(opcode_op0_sel==4'h9) ? { 8'h00 , register_flags } :
|
||||
(opcode_op0_sel==4'hA) ? address_out :
|
||||
(opcode_op0_sel==4'hB) ? { data_in_d2 , data_in_d2 } :
|
||||
(opcode_op0_sel==4'hC) ? system_status :
|
||||
(opcode_op0_sel==4'hD) ? { 11'h000 , system_output[4:0] } :
|
||||
//(opcode_op0_sel==4'hE) ? xxxx :
|
||||
16'h0 ;
|
||||
|
||||
|
||||
assign operand1 = (opcode_op1_sel==4'h0) ? register_r0 :
|
||||
(opcode_op1_sel==4'h1) ? register_r1 :
|
||||
(opcode_op1_sel==4'h2) ? register_r2 :
|
||||
(opcode_op1_sel==4'h3) ? register_r3 :
|
||||
(opcode_op1_sel==4'h4) ? { 8'h00 , register_a } :
|
||||
(opcode_op1_sel==4'h5) ? { 8'h00 , register_x } :
|
||||
(opcode_op1_sel==4'h6) ? { 8'h00 , register_y } :
|
||||
(opcode_op1_sel==4'h7) ? { register_pc[7:0] , register_pc[15:8] } :
|
||||
(opcode_op1_sel==4'h8) ? { 8'h01 , register_sp } :
|
||||
(opcode_op1_sel==4'h9) ? { 8'h00 , register_flags } :
|
||||
(opcode_op1_sel==4'hA) ? address_out :
|
||||
(opcode_op1_sel==4'hB) ? { data_in_d2 , data_in_d2 } :
|
||||
(opcode_op1_sel==4'hC) ? system_status :
|
||||
|
||||
assign operand1 = (opcode_op1_sel==4'h0) ? register_r0 :
|
||||
(opcode_op1_sel==4'h1) ? register_r1 :
|
||||
(opcode_op1_sel==4'h2) ? register_r2 :
|
||||
(opcode_op1_sel==4'h3) ? register_r3 :
|
||||
(opcode_op1_sel==4'h4) ? { 8'h00 , register_a } :
|
||||
(opcode_op1_sel==4'h5) ? { 8'h00 , register_x } :
|
||||
(opcode_op1_sel==4'h6) ? { 8'h00 , register_y } :
|
||||
(opcode_op1_sel==4'h7) ? { register_pc[7:0] , register_pc[15:8] } :
|
||||
(opcode_op1_sel==4'h8) ? { 8'h01 , register_sp } :
|
||||
(opcode_op1_sel==4'h9) ? { 8'h00 , register_flags } :
|
||||
(opcode_op1_sel==4'hA) ? address_out :
|
||||
(opcode_op1_sel==4'hB) ? { data_in_d2 , data_in_d2 } :
|
||||
(opcode_op1_sel==4'hC) ? system_status :
|
||||
(opcode_op1_sel==4'hD) ? { 11'h000 , system_output[4:0] } :
|
||||
//(opcode_op1_sel==4'hE) ? xxxx :
|
||||
opcode_immediate ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// JUMP condition codes
|
||||
assign jump_boolean = (opcode_jump_cond==4'h0) ? 1'b1 : // Unconditional jump
|
||||
(opcode_jump_cond==4'h1 && alu_last_result!=16'h0) ? 1'b1 : // Jump Not Zero
|
||||
(opcode_jump_cond==4'h2 && alu_last_result==16'h0) ? 1'b1 : // Jump Zero
|
||||
(opcode_jump_cond==4'h3 && clk0_int_d2==1'b0) ? 1'b1 : // Jump backwards until CLK=1
|
||||
(opcode_jump_cond==4'h4 && rdwr_n_int_d1==1'b0 && clk0_int_d2==1'b1) ? 1'b1 : // Jump backwards until CLK=0 for write cycles. READY ignored
|
||||
(opcode_jump_cond==4'h4 && rdwr_n_int_d1==1'b1 && (clk0_int_d2==1'b1 || ready_int_d3==1'b0)) ? 1'b1 : // Jump backwards until CLK=0 for read cycles with READY active
|
||||
1'b0 ;
|
||||
assign jump_boolean = (opcode_jump_cond==4'h0) ? 1'b1 : // Unconditional jump
|
||||
(opcode_jump_cond==4'h1 && alu_last_result!=16'h0) ? 1'b1 : // Jump Not Zero
|
||||
(opcode_jump_cond==4'h2 && alu_last_result==16'h0) ? 1'b1 : // Jump Zero
|
||||
(opcode_jump_cond==4'h3 && clk0_int_d2==1'b0) ? 1'b1 : // Jump backwards until CLK=1
|
||||
(opcode_jump_cond==4'h4 && rdwr_n_int_d1==1'b0 && clk0_int_d2==1'b1) ? 1'b1 : // Jump backwards until CLK=0 for write cycles. READY ignored
|
||||
(opcode_jump_cond==4'h4 && rdwr_n_int_d1==1'b1 && (clk0_int_d2==1'b1 || ready_int_d3==1'b0)) ? 1'b1 : // Jump backwards until CLK=0 for read cycles with READY active
|
||||
1'b0 ;
|
||||
|
||||
|
||||
|
||||
// System status
|
||||
assign system_status[15:7] = 'h0;
|
||||
assign system_status[6] = add_overflow8;
|
||||
assign system_status[5] = irq_gated;
|
||||
assign system_status[4] = so_asserted;
|
||||
assign system_status[3] = nmi_asserted;
|
||||
assign system_status[2] = 1'b0;
|
||||
assign system_status[1] = 1'b0;
|
||||
assign system_status[0] = add_carry8;
|
||||
|
||||
// System status
|
||||
assign system_status[15:7] = 'h0;
|
||||
assign system_status[6] = add_overflow8;
|
||||
assign system_status[5] = irq_gated;
|
||||
assign system_status[4] = so_asserted;
|
||||
assign system_status[3] = nmi_asserted;
|
||||
assign system_status[2] = 1'b0;
|
||||
assign system_status[1] = 1'b0;
|
||||
assign system_status[0] = add_carry8;
|
||||
|
||||
|
||||
assign flag_n = register_flags[7];
|
||||
assign flag_v = register_flags[6];
|
||||
assign flag_n = register_flags[7];
|
||||
assign flag_v = register_flags[6];
|
||||
|
||||
assign flag_b = register_flags[4];
|
||||
assign flag_d = register_flags[3];
|
||||
assign flag_i = register_flags[2];
|
||||
assign flag_z = register_flags[1];
|
||||
assign flag_c = register_flags[0];
|
||||
assign flag_b = register_flags[4];
|
||||
assign flag_d = register_flags[3];
|
||||
assign flag_i = register_flags[2];
|
||||
assign flag_z = register_flags[1];
|
||||
assign flag_c = register_flags[0];
|
||||
|
||||
|
||||
|
||||
|
@ -267,11 +288,11 @@ assign flag_c = register_flags[0];
|
|||
// ------------------------------------------
|
||||
// alu0 = NOP
|
||||
// alu1 = JUMP
|
||||
assign alu2 = adder_out; // ADD
|
||||
assign alu3 = operand0 & operand1; // AND
|
||||
assign alu4 = operand0 | operand1; // OR
|
||||
assign alu5 = operand0 ^ operand1; // XOR
|
||||
assign alu6 = { 1'b0 , operand0[15:1] }; // SHR
|
||||
assign alu2 = adder_out; // ADD
|
||||
assign alu3 = operand0 & operand1; // AND
|
||||
assign alu4 = operand0 | operand1; // OR
|
||||
assign alu5 = operand0 ^ operand1; // XOR
|
||||
assign alu6 = { 1'b0 , operand0[15:1] }; // SHR
|
||||
|
||||
|
||||
|
||||
|
@ -284,7 +305,7 @@ assign alu_out = (opcode_type==3'h2) ? alu2 :
|
|||
(opcode_type==3'h6) ? alu6 :
|
||||
16'hEEEE;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -294,8 +315,8 @@ genvar i;
|
|||
generate
|
||||
for (i=0; i < 16; i=i+1)
|
||||
begin : GEN_ADDER
|
||||
assign adder_out[i] = operand0[i] ^ operand1[i] ^ carry[i];
|
||||
assign carry[i+1] = (operand0[i] & operand1[i]) | (operand0[i] & carry[i]) | (operand1[i] & carry[i]);
|
||||
assign adder_out[i] = operand0[i] ^ operand1[i] ^ carry[i];
|
||||
assign carry[i+1] = (operand0[i] & operand1[i]) | (operand0[i] & carry[i]) | (operand1[i] & carry[i]);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
@ -310,142 +331,142 @@ endgenerate
|
|||
always @(posedge CORE_CLK)
|
||||
begin : MICROSEQUENCER
|
||||
|
||||
clk0_int_d1 <= CLK0;
|
||||
clk0_int_d2 <= clk0_int_d1;
|
||||
clk0_int_d3 <= clk0_int_d2;
|
||||
clk0_int_d4 <= clk0_int_d3;
|
||||
|
||||
clk1_out_int <= ~clk0_int_d3;
|
||||
clk2_out_int <= clk0_int_d2;
|
||||
|
||||
reset_n_d1 <= RESET_n;
|
||||
reset_n_d2 <= reset_n_d1;
|
||||
|
||||
ready_int_d1 <= READY;
|
||||
ready_int_d2 <= ready_int_d1;
|
||||
ready_int_d3 <= ready_int_d2;
|
||||
|
||||
sync_int_d1 <= sync_int;
|
||||
rdwr_n_int_d1 <= rdwr_n_int;
|
||||
rdwr_n_int_d2 <= rdwr_n_int_d1;
|
||||
|
||||
a_out_int <= address_out;
|
||||
d_out_int <= data_out;
|
||||
|
||||
irq_d1 <= ~IRQ_n;
|
||||
data_in_d1 <= D;
|
||||
if (clk0_int_d3==1'b1 && clk0_int_d2==1'b0) // Store data and sample IRQ_n on falling edge of clk
|
||||
begin
|
||||
data_in_d2 <= data_in_d1;
|
||||
irq_d2 <= irq_d1;
|
||||
irq_d3 <= irq_d2;
|
||||
irq_d4 <= irq_d3;
|
||||
clk0_int_d1 <= CLK0;
|
||||
clk0_int_d2 <= clk0_int_d1;
|
||||
clk0_int_d3 <= clk0_int_d2;
|
||||
clk0_int_d4 <= clk0_int_d3;
|
||||
|
||||
clk1_out_int <= ~clk0_int_d3;
|
||||
clk2_out_int <= clk0_int_d2;
|
||||
|
||||
reset_n_d1 <= RESET_n;
|
||||
reset_n_d2 <= reset_n_d1;
|
||||
|
||||
ready_int_d1 <= READY;
|
||||
ready_int_d2 <= ready_int_d1;
|
||||
ready_int_d3 <= ready_int_d2;
|
||||
|
||||
sync_int_d1 <= sync_int;
|
||||
rdwr_n_int_d1 <= rdwr_n_int;
|
||||
rdwr_n_int_d2 <= rdwr_n_int_d1;
|
||||
|
||||
a_out_int <= address_out;
|
||||
d_out_int <= data_out;
|
||||
|
||||
irq_d1 <= ~IRQ_n;
|
||||
data_in_d1 <= D;
|
||||
if (clk0_int_d3==1'b1 && clk0_int_d2==1'b0) // Store data and sample IRQ_n on falling edge of clk
|
||||
begin
|
||||
data_in_d2 <= data_in_d1;
|
||||
irq_d2 <= irq_d1;
|
||||
irq_d3 <= irq_d2;
|
||||
irq_d4 <= irq_d3;
|
||||
end
|
||||
|
||||
irq_gated <= irq_d4 & ~flag_i;
|
||||
irq_gated <= irq_d4 & ~flag_i;
|
||||
|
||||
if (rdwr_n_int_d1==1'b0 && clk0_int_d4==1'b1)
|
||||
begin
|
||||
dataout_enable <= 1'b1;
|
||||
end
|
||||
else if (rdwr_n_int_d2==1'b0 && rdwr_n_int_d1==1'b1)
|
||||
begin
|
||||
dataout_enable <= 1'b0;
|
||||
end
|
||||
|
||||
nmi_n_d1 <= NMI_n;
|
||||
nmi_n_d2 <= nmi_n_d1;
|
||||
nmi_n_d3 <= nmi_n_d2;
|
||||
if (nmi_debounce==1'b1)
|
||||
begin
|
||||
nmi_asserted <= 1'b0;
|
||||
end
|
||||
else if (nmi_n_d3==1'b1 && nmi_n_d2==1'b0) // Falling edge of NMI_n
|
||||
begin
|
||||
nmi_asserted <= 1'b1;
|
||||
end
|
||||
|
||||
so_n_d1 <= SO;
|
||||
so_n_d2 <=so_n_d1;
|
||||
so_n_d3 <=so_n_d2;
|
||||
if (so_debounce==1'b1)
|
||||
begin
|
||||
so_asserted <= 1'b0;
|
||||
end
|
||||
else if (so_n_d3==1'b1 && so_n_d2==1'b0) // Falling edge of SO
|
||||
begin
|
||||
so_asserted <= 1'b1;
|
||||
end
|
||||
|
||||
|
||||
|
||||
// Generate and store flags for addition
|
||||
if (stall_pipeline==1'b0 && opcode_type==3'h2)
|
||||
begin
|
||||
add_carry8 <= carry[8];
|
||||
add_overflow8 <= carry[8] ^ carry[7];
|
||||
if (rdwr_n_int_d1==1'b0 && clk0_int_d4==1'b1)
|
||||
begin
|
||||
dataout_enable <= 1'b1;
|
||||
end
|
||||
else if (rdwr_n_int_d2==1'b0 && rdwr_n_int_d1==1'b1)
|
||||
begin
|
||||
dataout_enable <= 1'b0;
|
||||
end
|
||||
|
||||
nmi_n_d1 <= NMI_n;
|
||||
nmi_n_d2 <= nmi_n_d1;
|
||||
nmi_n_d3 <= nmi_n_d2;
|
||||
if (nmi_debounce==1'b1)
|
||||
begin
|
||||
nmi_asserted <= 1'b0;
|
||||
end
|
||||
else if (nmi_n_d3==1'b1 && nmi_n_d2==1'b0) // Falling edge of NMI_n
|
||||
begin
|
||||
nmi_asserted <= 1'b1;
|
||||
end
|
||||
|
||||
|
||||
// Register writeback
|
||||
so_n_d1 <= SO;
|
||||
so_n_d2 <=so_n_d1;
|
||||
so_n_d3 <=so_n_d2;
|
||||
if (so_debounce==1'b1)
|
||||
begin
|
||||
so_asserted <= 1'b0;
|
||||
end
|
||||
else if (so_n_d3==1'b1 && so_n_d2==1'b0) // Falling edge of SO
|
||||
begin
|
||||
so_asserted <= 1'b1;
|
||||
end
|
||||
|
||||
|
||||
|
||||
// Generate and store flags for addition
|
||||
if (stall_pipeline==1'b0 && opcode_type==3'h2)
|
||||
begin
|
||||
add_carry8 <= carry[8];
|
||||
add_overflow8 <= carry[8] ^ carry[7];
|
||||
end
|
||||
|
||||
|
||||
// Register writeback
|
||||
if (stall_pipeline==1'b0 && opcode_type!=3'h0 && opcode_type!=3'h1)
|
||||
begin
|
||||
alu_last_result <= alu_out[15:0];
|
||||
case (opcode_dst_sel) // synthesis parallel_case
|
||||
4'h0 : register_r0 <= alu_out[15:0];
|
||||
4'h1 : register_r1 <= alu_out[15:0];
|
||||
4'h2 : register_r2 <= alu_out[15:0];
|
||||
4'h3 : register_r3 <= alu_out[15:0];
|
||||
4'h4 : register_a <= alu_out[7:0];
|
||||
4'h5 : register_x <= alu_out[7:0];
|
||||
4'h6 : register_y <= alu_out[7:0];
|
||||
4'h7 : register_pc <= alu_out[15:0];
|
||||
4'h8 : register_sp <= alu_out[7:0];
|
||||
4'h9 : register_flags <= { alu_out[7:6] , 2'b11 , alu_out[3:0] };
|
||||
4'hA : address_out <= alu_out[15:0];
|
||||
4'hB : data_out <= alu_out[7:0];
|
||||
//4'hC :
|
||||
4'hD : system_output <= alu_out[4:0];
|
||||
//4'hE :
|
||||
//4'hF :
|
||||
default : ;
|
||||
endcase
|
||||
begin
|
||||
alu_last_result <= alu_out[15:0];
|
||||
case (opcode_dst_sel) // synthesis parallel_case
|
||||
4'h0 : register_r0 <= alu_out[15:0];
|
||||
4'h1 : register_r1 <= alu_out[15:0];
|
||||
4'h2 : register_r2 <= alu_out[15:0];
|
||||
4'h3 : register_r3 <= alu_out[15:0];
|
||||
4'h4 : register_a <= alu_out[7:0];
|
||||
4'h5 : register_x <= alu_out[7:0];
|
||||
4'h6 : register_y <= alu_out[7:0];
|
||||
4'h7 : register_pc <= alu_out[15:0];
|
||||
4'h8 : register_sp <= alu_out[7:0];
|
||||
4'h9 : register_flags <= { alu_out[7:6] , 2'b11 , alu_out[3:0] };
|
||||
4'hA : address_out <= alu_out[15:0];
|
||||
4'hB : data_out <= alu_out[7:0];
|
||||
//4'hC :
|
||||
4'hD : system_output <= alu_out[4:0];
|
||||
//4'hE :
|
||||
//4'hF :
|
||||
default : ;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
if (reset_n_d2==1'b0)
|
||||
|
||||
if (reset_n_d2==1'b0)
|
||||
begin
|
||||
rom_address <= 11'h7D0; // Microcode starts here after reset
|
||||
stall_pipeline <= 'h0;
|
||||
stall_pipeline <= 'h0;
|
||||
end
|
||||
|
||||
// JUMP Opcode
|
||||
// JUMP Opcode
|
||||
else if (stall_pipeline==1'b0 && opcode_type==3'h1 && jump_boolean==1'b1)
|
||||
begin
|
||||
stall_pipeline <= 1'b1;
|
||||
|
||||
// For subroutine CALLs, store next opcode address
|
||||
if (opcode_jump_call==1'b1)
|
||||
begin
|
||||
calling_address[21:0] <= {calling_address[10:0] , rom_address[10:0] }; // Two deep stack for calling addresses
|
||||
end
|
||||
begin
|
||||
stall_pipeline <= 1'b1;
|
||||
|
||||
// For subroutine CALLs, store next opcode address
|
||||
if (opcode_jump_call==1'b1)
|
||||
begin
|
||||
calling_address[21:0] <= {calling_address[10:0] , rom_address[10:0] }; // Two deep stack for calling addresses
|
||||
end
|
||||
|
||||
case (opcode_jump_src) // synthesis parallel_case
|
||||
3'h0 : rom_address <= opcode_immediate[10:0];
|
||||
3'h1 : rom_address <= { 3'b000 , data_in_d2[7:0] }; // Opcode Jump Table
|
||||
3'h2 : begin
|
||||
rom_address <= calling_address[10:0];
|
||||
calling_address[10:0] <= calling_address[21:11];
|
||||
end
|
||||
3'h3 : rom_address <= rom_address - 1'b1;
|
||||
default : ;
|
||||
endcase
|
||||
end
|
||||
|
||||
case (opcode_jump_src) // synthesis parallel_case
|
||||
3'h0 : rom_address <= opcode_immediate[10:0];
|
||||
3'h1 : rom_address <= { 3'b000 , data_in_d2[7:0] }; // Opcode Jump Table
|
||||
3'h2 : begin
|
||||
rom_address <= calling_address[10:0];
|
||||
calling_address[10:0] <= calling_address[21:11];
|
||||
end
|
||||
3'h3 : rom_address <= rom_address - 1'b1;
|
||||
default : ;
|
||||
endcase
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
stall_pipeline <= 1'b0; // Debounce the pipeline stall
|
||||
rom_address <= rom_address + 1'b1;
|
||||
stall_pipeline <= 1'b0; // Debounce the pipeline stall
|
||||
rom_address <= rom_address + 1'b1;
|
||||
end
|
||||
|
||||
end // MCL65 Microsequencer
|
||||
|
|
|
@ -1,8 +1,50 @@
|
|||
//
|
||||
// Microcode for the MCL65
|
||||
//
|
||||
// File Name : Microcode_MCL65.txt
|
||||
// Used on : MCL65
|
||||
// Author : Ted Fried, MicroCore Labs
|
||||
// Creation : 1/25/2020
|
||||
// Code Type : Microcode
|
||||
//
|
||||
// Description:
|
||||
// ============
|
||||
//
|
||||
// Microcode for the MCL65
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Modification History:
|
||||
// =====================
|
||||
//
|
||||
// Revision 1.0 1/25/2020
|
||||
// Initial revision
|
||||
//
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2020 Ted Fried
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// Microcode and microsequencer notes:
|
||||
//
|
||||
// System status register
|
||||
// assign system_status[15:7] = 'h0;
|
|
@ -1,37 +1,69 @@
|
|||
#
|
||||
# Microcode for the MCL86
|
||||
#
|
||||
# ------------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2019 by Ted Fried info@MicroCoreLabs.com
|
||||
#
|
||||
# Permission to use, copy, modify, and distribute this software and its
|
||||
# documentation for any purpose and without fee is hereby granted, provided
|
||||
# that the above copyright notice appear in all copies and that both that
|
||||
# copyright notice and this permission notice appear in supporting documentation.
|
||||
# This software is provided "as is" without express or implied warranty.
|
||||
#
|
||||
# ------------------------------------------------------------------------
|
||||
#
|
||||
//
|
||||
//
|
||||
// File Name : Microcode_MCL86.txt
|
||||
// Used on : MCL86
|
||||
// Author : Ted Fried, MicroCore Labs
|
||||
// Creation : 1/25/2020
|
||||
// Code Type : Microcode
|
||||
//
|
||||
// Description:
|
||||
// ============
|
||||
//
|
||||
// Microcode for the MCL86
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Modification History:
|
||||
// =====================
|
||||
//
|
||||
// Revision 1.0 1/25/2020
|
||||
// Initial revision
|
||||
//
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2020 Ted Fried
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
// Microcode and microsequencer notes:
|
||||
//
|
||||
#
|
||||
# // Consolidated system signals
|
||||
# assign system_signals[15]
|
||||
# assign system_signals[14]
|
||||
# assign system_signals[13] = eu_add_carry8;
|
||||
# assign system_signals[12] = clock_cycle_counter_zero;
|
||||
# assign system_signals[11] = eu_add_overflow16;
|
||||
# assign system_signals[13] = eu_add_carry8;
|
||||
# assign system_signals[12] = clock_cycle_counter_zero;
|
||||
# assign system_signals[11] = eu_add_overflow16;
|
||||
# assign system_signals[10]
|
||||
# assign system_signals[9] = eu_add_overflow8;
|
||||
# assign system_signals[8] = eu_flag_t_asserted;
|
||||
# assign system_signals[7] = ~pfq_empty;
|
||||
# assign system_signals[6] = biu_done_caught;
|
||||
# assign system_signals[5] = test_n_int;
|
||||
# assign system_signals[4] = eu_add_aux_carry;
|
||||
# assign system_signals[3] = nmi_caught;
|
||||
# assign system_signals[2] = eu_parity;
|
||||
# assign system_signals[1] = int_asserted;
|
||||
# assign system_signals[0] = eu_add_carry16;
|
||||
# assign system_signals[9] = eu_add_overflow8;
|
||||
# assign system_signals[8] = eu_flag_t_asserted;
|
||||
# assign system_signals[7] = ~pfq_empty;
|
||||
# assign system_signals[6] = biu_done_caught;
|
||||
# assign system_signals[5] = test_n_int;
|
||||
# assign system_signals[4] = eu_add_aux_carry;
|
||||
# assign system_signals[3] = nmi_caught;
|
||||
# assign system_signals[2] = eu_parity;
|
||||
# assign system_signals[1] = int_asserted;
|
||||
# assign system_signals[0] = eu_add_carry16;
|
||||
#
|
||||
#
|
||||
# assign eu_prefix_repnz = eu_flags[15];
|
||||
|
@ -46,9 +78,9 @@
|
|||
# assign eu_flag_z = eu_flags[6];
|
||||
# assign eu_tf_debounce = eu_flags[5];
|
||||
# assign eu_flag_a = eu_flags[4];
|
||||
# assign eu_flag_temp = eu_flags[3];
|
||||
# assign eu_flag_temp = eu_flags[3];
|
||||
# assign eu_flag_p = eu_flags[2];
|
||||
# assign eu_flag_temp = eu_flags[1];
|
||||
# assign eu_flag_temp = eu_flags[1];
|
||||
# assign eu_flag_c = eu_flags[0];
|
||||
#
|
||||
#
|
||||
|
@ -58,7 +90,7 @@
|
|||
# // eu_biu_strobe[1:0] are available for only one clock cycle and cause BIU to take immediate action.
|
||||
# // eu_biu_req stays asserted until the BIU is available to service the request.
|
||||
# //
|
||||
# = eu_biu_command[15];
|
||||
# = eu_biu_command[15];
|
||||
# eu_segment_override = eu_biu_command[14];
|
||||
# eu_biu_strobe[1:0] = eu_biu_command[13:12]; // 01=opcode fetch 10=clock load 11=load biu register(eu_biu_req_code has the register#)
|
||||
# eu_biu_segment[1:0] = eu_biu_command[11:10];
|
||||
|
@ -66,29 +98,29 @@
|
|||
# eu_biu_req_code = eu_biu_command[8:4];
|
||||
# eu_qs_out[1:0] = eu_biu_command[3:2]; // Updated for every opcode fetch strobe using biu_strobe and Jump request using eu_biu_rq
|
||||
# eu_segment_override_value[1:0] = eu_biu_command[1:0];
|
||||
#
|
||||
#
|
||||
#
|
||||
# EU Registers
|
||||
# --------------
|
||||
#
|
||||
# Destination Operand0 Operand1
|
||||
# Destination Operand0 Operand1
|
||||
# -----------------------------------------------------------------------------------------------
|
||||
# 0 AX 0 AX 0 ES
|
||||
# 1 BX 1 BX 1 SS
|
||||
# 2 CX 2 CX 2 CS
|
||||
# 3 DX 3 DX 3 DS
|
||||
# 4 SP 4 SP 4 { 8'h00 , pfq_top_byte }
|
||||
# 5 BP 5 BP 5 EA_RM from BIU
|
||||
# 6 SI 6 SI 6 EA_REG from BIU
|
||||
# 7 DI 7 DI 7 BIU Return Data
|
||||
# 8 Flags 8 Flags 8 Prefetch Queue Address (Current IP)
|
||||
# 9 r0 9 r0 9 r0
|
||||
# A r1 A r1 A r1
|
||||
# B r2 B r2 B r2
|
||||
# C r3 C r3 C r3
|
||||
# D BIU Command D BIU Command D ALU Last Result
|
||||
# E Dummy Reg E System Signals E System Signals
|
||||
# F BIU Dataout F 16'h0000 F Opcode Immediate[15:0]
|
||||
# 0 AX 0 AX 0 ES
|
||||
# 1 BX 1 BX 1 SS
|
||||
# 2 CX 2 CX 2 CS
|
||||
# 3 DX 3 DX 3 DS
|
||||
# 4 SP 4 SP 4 { 8'h00 , pfq_top_byte }
|
||||
# 5 BP 5 BP 5 EA_RM from BIU
|
||||
# 6 SI 6 SI 6 EA_REG from BIU
|
||||
# 7 DI 7 DI 7 BIU Return Data
|
||||
# 8 Flags 8 Flags 8 Prefetch Queue Address (Current IP)
|
||||
# 9 r0 9 r0 9 r0
|
||||
# A r1 A r1 A r1
|
||||
# B r2 B r2 B r2
|
||||
# C r3 C r3 C r3
|
||||
# D BIU Command D BIU Command D ALU Last Result
|
||||
# E Dummy Reg E System Signals E System Signals
|
||||
# F BIU Dataout F 16'h0000 F Opcode Immediate[15:0]
|
||||
#
|
||||
#
|
||||
# EU Opcodes
|
||||
|
@ -97,19 +129,19 @@
|
|||
# ----------------
|
||||
# Bits[31:28] : 0x1
|
||||
# Bits[27:24] : CALL 1=Store next IP address
|
||||
# Bits[22:20] : Jump Source:
|
||||
# 0x0=Immediate[12:0]
|
||||
# 0x1={immediate[4:0]&pfq_top_byte}
|
||||
# 0x2={immediate[4:0]&pfq_top_byte[7:6]&pfq_top_byte[2:0]&000}
|
||||
# 0x3=Return to CALL stored IP address
|
||||
# 0x4={immediate[8:0], eu_biu_dataout[3:0] , 1'b0 } // For register fetch
|
||||
# 0x5={immediate[7:0], eu_biu_dataout[3:0] , 2'b00 } // For register writeback
|
||||
# 0x6={eu_opcode_immediate[12:3], eu_biu_dataout[5:3]} // For opcode group decoding
|
||||
# Bits[22:20] : Jump Source:
|
||||
# 0x0=Immediate[12:0]
|
||||
# 0x1={immediate[4:0]&pfq_top_byte}
|
||||
# 0x2={immediate[4:0]&pfq_top_byte[7:6]&pfq_top_byte[2:0]&000}
|
||||
# 0x3=Return to CALL stored IP address
|
||||
# 0x4={immediate[8:0], eu_biu_dataout[3:0] , 1'b0 } // For register fetch
|
||||
# 0x5={immediate[7:0], eu_biu_dataout[3:0] , 2'b00 } // For register writeback
|
||||
# 0x6={eu_opcode_immediate[12:3], eu_biu_dataout[5:3]} // For opcode group decoding
|
||||
#
|
||||
# Bits[19:16] : Jump Condition:
|
||||
# 0x0=Unconditional
|
||||
# 0x1=Last_ALU_Result!=0
|
||||
# 0x2=Last_ALU_Result==0
|
||||
# Bits[19:16] : Jump Condition:
|
||||
# 0x0=Unconditional
|
||||
# 0x1=Last_ALU_Result!=0
|
||||
# 0x2=Last_ALU_Result==0
|
||||
# Bits[12:0] : Immediate[12:0]
|
||||
#
|
||||
# 0x2 - ADD
|
||||
|
@ -141,14 +173,14 @@
|
|||
# (eu_biu_req_code == h14 ===> Memory Word Write - To Stack Segment
|
||||
# (eu_biu_req_code == h16 ===> Interrupt ACK Cycle
|
||||
# (eu_biu_req_code == h18 ===> HALT State
|
||||
# (eu_biu_req_code == h19 ===> Jump Instruction
|
||||
# (eu_biu_req_code == h19 ===> Jump Instruction
|
||||
# (eu_biu_req_code == h1A ===> IO Word Read
|
||||
# (eu_biu_req_code == h1C ===> IO Word Write
|
||||
# (eu_biu_req_code == h1C ===> IO Word Write
|
||||
# RESET State
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
# Stop CPU
|
||||
p 00 00000 00010 0001
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
380
MCL86/Core/eu.v
380
MCL86/Core/eu.v
|
@ -2,7 +2,7 @@
|
|||
//
|
||||
// File Name : mcl86_eu_core.v
|
||||
// Used on :
|
||||
// Author : MicroCore Labs
|
||||
// Author : Ted Fried, MicroCore Labs
|
||||
// Creation : 10/8/2015
|
||||
// Code Type : Synthesizable
|
||||
//
|
||||
|
@ -21,46 +21,68 @@
|
|||
//
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2020 Ted Fried
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
module mcl86_eu_core
|
||||
(
|
||||
input CORE_CLK_INT, // Core Clock
|
||||
input RESET_INT, // Pipelined 8088 RESET pin
|
||||
input TEST_N_INT, // Pipelined 8088 TEST_n pin
|
||||
input CORE_CLK_INT, // Core Clock
|
||||
input RESET_INT, // Pipelined 8088 RESET pin
|
||||
input TEST_N_INT, // Pipelined 8088 TEST_n pin
|
||||
|
||||
|
||||
output [15:0] EU_BIU_COMMAND, // EU to BIU Signals
|
||||
output [15:0] EU_BIU_DATAOUT,
|
||||
output [15:0] EU_REGISTER_R3,
|
||||
output EU_PREFIX_LOCK,
|
||||
output EU_FLAG_I,
|
||||
|
||||
|
||||
input BIU_DONE, // BIU to EU Signals
|
||||
input BIU_CLK_COUNTER_ZERO,
|
||||
input BIU_NMI_CAUGHT,
|
||||
output BIU_NMI_DEBOUNCE,
|
||||
input BIU_INTR,
|
||||
|
||||
output [15:0] EU_BIU_COMMAND, // EU to BIU Signals
|
||||
output [15:0] EU_BIU_DATAOUT,
|
||||
output [15:0] EU_REGISTER_R3,
|
||||
output EU_PREFIX_LOCK,
|
||||
output EU_FLAG_I,
|
||||
|
||||
|
||||
input BIU_DONE, // BIU to EU Signals
|
||||
input BIU_CLK_COUNTER_ZERO,
|
||||
input BIU_NMI_CAUGHT,
|
||||
output BIU_NMI_DEBOUNCE,
|
||||
input BIU_INTR,
|
||||
|
||||
|
||||
input [7:0] PFQ_TOP_BYTE,
|
||||
input PFQ_EMPTY,
|
||||
input[15:0] PFQ_ADDR_OUT,
|
||||
|
||||
input [7:0] PFQ_TOP_BYTE,
|
||||
input PFQ_EMPTY,
|
||||
input[15:0] PFQ_ADDR_OUT,
|
||||
|
||||
|
||||
input [15:0] BIU_REGISTER_ES,
|
||||
input [15:0] BIU_REGISTER_SS,
|
||||
input [15:0] BIU_REGISTER_CS,
|
||||
input [15:0] BIU_REGISTER_DS,
|
||||
input [15:0] BIU_REGISTER_RM,
|
||||
input [15:0] BIU_REGISTER_REG,
|
||||
input [15:0] BIU_RETURN_DATA
|
||||
|
||||
input [15:0] BIU_REGISTER_ES,
|
||||
input [15:0] BIU_REGISTER_SS,
|
||||
input [15:0] BIU_REGISTER_CS,
|
||||
input [15:0] BIU_REGISTER_DS,
|
||||
input [15:0] BIU_REGISTER_RM,
|
||||
input [15:0] BIU_REGISTER_REG,
|
||||
input [15:0] BIU_RETURN_DATA
|
||||
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
// Internal Signals
|
||||
|
||||
|
@ -140,13 +162,13 @@ wire [31:0] eu_rom_data;
|
|||
//
|
||||
// EU Microcode RAM. 4Kx32 DPRAM
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
eu_rom EU_4Kx32 (
|
||||
eu_rom EU_4Kx32 (
|
||||
|
||||
.clka (CORE_CLK_INT),
|
||||
.addra (eu_rom_address[11:0]),
|
||||
.douta (eu_rom_data)
|
||||
.clka (CORE_CLK_INT),
|
||||
.addra (eu_rom_address[11:0]),
|
||||
.douta (eu_rom_data)
|
||||
|
||||
);
|
||||
|
||||
|
@ -158,23 +180,23 @@ eu_rom EU_4Kx32 (
|
|||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
assign EU_BIU_COMMAND = eu_biu_command;
|
||||
assign EU_BIU_DATAOUT = eu_biu_dataout;
|
||||
assign EU_REGISTER_R3 = eu_register_r3;
|
||||
assign EU_FLAG_I = intr_enable_delayed;
|
||||
assign EU_PREFIX_LOCK = eu_prefix_lock;
|
||||
assign EU_BIU_COMMAND = eu_biu_command;
|
||||
assign EU_BIU_DATAOUT = eu_biu_dataout;
|
||||
assign EU_REGISTER_R3 = eu_register_r3;
|
||||
assign EU_FLAG_I = intr_enable_delayed;
|
||||
assign EU_PREFIX_LOCK = eu_prefix_lock;
|
||||
|
||||
|
||||
// EU ROM opcode decoder
|
||||
assign eu_opcode_type = eu_rom_data[30:28];
|
||||
assign eu_opcode_dst_sel = eu_rom_data[27:24];
|
||||
assign eu_opcode_op0_sel = eu_rom_data[23:20];
|
||||
assign eu_opcode_op1_sel = eu_rom_data[19:16];
|
||||
assign eu_opcode_type = eu_rom_data[30:28];
|
||||
assign eu_opcode_dst_sel = eu_rom_data[27:24];
|
||||
assign eu_opcode_op0_sel = eu_rom_data[23:20];
|
||||
assign eu_opcode_op1_sel = eu_rom_data[19:16];
|
||||
assign eu_opcode_immediate = eu_rom_data[15:0];
|
||||
|
||||
assign eu_opcode_jump_call = eu_rom_data[24];
|
||||
assign eu_opcode_jump_src = eu_rom_data[22:20];
|
||||
assign eu_opcode_jump_cond = eu_rom_data[19:16];
|
||||
assign eu_opcode_jump_call = eu_rom_data[24];
|
||||
assign eu_opcode_jump_src = eu_rom_data[22:20];
|
||||
assign eu_opcode_jump_cond = eu_rom_data[19:16];
|
||||
|
||||
|
||||
|
||||
|
@ -195,7 +217,7 @@ assign eu_operand0 = (eu_opcode_op0_sel==4'h0) ? eu_register_ax :
|
|||
(eu_opcode_op0_sel==4'hE) ? system_signals :
|
||||
16'h0 ;
|
||||
|
||||
|
||||
|
||||
assign eu_operand1 = (eu_opcode_op1_sel==4'h0) ? BIU_REGISTER_ES :
|
||||
(eu_opcode_op1_sel==4'h1) ? BIU_REGISTER_SS :
|
||||
(eu_opcode_op1_sel==4'h2) ? BIU_REGISTER_CS :
|
||||
|
@ -219,42 +241,42 @@ assign eu_operand1 = (eu_opcode_op1_sel==4'h0) ? BIU_REGISTER_ES :
|
|||
assign eu_jump_boolean = (eu_opcode_jump_cond==4'h0) ? 1'b1 : // unconditional jump
|
||||
(eu_opcode_jump_cond==4'h1 && eu_alu_last_result!=16'h0) ? 1'b1 :
|
||||
(eu_opcode_jump_cond==4'h2 && eu_alu_last_result==16'h0) ? 1'b1 :
|
||||
1'b0 ;
|
||||
1'b0 ;
|
||||
|
||||
|
||||
|
||||
|
||||
// Consolidated system signals
|
||||
assign system_signals[13] = eu_add_carry8;
|
||||
assign system_signals[12] = BIU_CLK_COUNTER_ZERO;
|
||||
assign system_signals[11] = eu_add_overflow16;
|
||||
assign system_signals[9] = eu_add_overflow8;
|
||||
assign system_signals[8] = eu_tr_latched;
|
||||
assign system_signals[7] = ~PFQ_EMPTY;
|
||||
assign system_signals[6] = biu_done_caught;
|
||||
assign system_signals[5] = TEST_N_INT;
|
||||
assign system_signals[4] = eu_add_aux_carry;
|
||||
assign system_signals[3] = BIU_NMI_CAUGHT;
|
||||
assign system_signals[2] = eu_parity;
|
||||
assign system_signals[1] = intr_asserted;
|
||||
assign system_signals[0] = eu_add_carry;
|
||||
assign system_signals[13] = eu_add_carry8;
|
||||
assign system_signals[12] = BIU_CLK_COUNTER_ZERO;
|
||||
assign system_signals[11] = eu_add_overflow16;
|
||||
assign system_signals[9] = eu_add_overflow8;
|
||||
assign system_signals[8] = eu_tr_latched;
|
||||
assign system_signals[7] = ~PFQ_EMPTY;
|
||||
assign system_signals[6] = biu_done_caught;
|
||||
assign system_signals[5] = TEST_N_INT;
|
||||
assign system_signals[4] = eu_add_aux_carry;
|
||||
assign system_signals[3] = BIU_NMI_CAUGHT;
|
||||
assign system_signals[2] = eu_parity;
|
||||
assign system_signals[1] = intr_asserted;
|
||||
assign system_signals[0] = eu_add_carry;
|
||||
|
||||
|
||||
assign eu_prefix_repnz = eu_flags[15];
|
||||
assign eu_prefix_rep = eu_flags[14];
|
||||
assign eu_prefix_lock = eu_flags[13];
|
||||
assign BIU_NMI_DEBOUNCE = eu_flags[12];
|
||||
assign eu_flag_o = eu_flags[11];
|
||||
assign eu_flag_d = eu_flags[10];
|
||||
assign eu_flag_i = eu_flags[9];
|
||||
assign eu_flag_t = eu_flags[8];
|
||||
assign eu_flag_s = eu_flags[7];
|
||||
assign eu_flag_z = eu_flags[6];
|
||||
assign eu_tf_debounce = eu_flags[5];
|
||||
assign eu_flag_a = eu_flags[4];
|
||||
assign eu_nmi_pending = eu_flags[3];
|
||||
assign eu_flag_p = eu_flags[2];
|
||||
assign eu_flag_temp = eu_flags[1];
|
||||
assign eu_flag_c = eu_flags[0];
|
||||
assign eu_prefix_repnz = eu_flags[15];
|
||||
assign eu_prefix_rep = eu_flags[14];
|
||||
assign eu_prefix_lock = eu_flags[13];
|
||||
assign BIU_NMI_DEBOUNCE = eu_flags[12];
|
||||
assign eu_flag_o = eu_flags[11];
|
||||
assign eu_flag_d = eu_flags[10];
|
||||
assign eu_flag_i = eu_flags[9];
|
||||
assign eu_flag_t = eu_flags[8];
|
||||
assign eu_flag_s = eu_flags[7];
|
||||
assign eu_flag_z = eu_flags[6];
|
||||
assign eu_tf_debounce = eu_flags[5];
|
||||
assign eu_flag_a = eu_flags[4];
|
||||
assign eu_nmi_pending = eu_flags[3];
|
||||
assign eu_flag_p = eu_flags[2];
|
||||
assign eu_flag_temp = eu_flags[1];
|
||||
assign eu_flag_c = eu_flags[0];
|
||||
|
||||
|
||||
|
||||
|
@ -262,12 +284,12 @@ assign eu_flag_c = eu_flags[0];
|
|||
// ------------------------------------------
|
||||
// eu_alu0 = NOP
|
||||
// eu_alu1 = JUMP
|
||||
assign eu_alu2 = adder_out; // ADD
|
||||
assign eu_alu3 = { eu_operand0[7:0] , eu_operand0[15:8] }; // BYTESWAP
|
||||
assign eu_alu4 = eu_operand0 & eu_operand1; // AND
|
||||
assign eu_alu5 = eu_operand0 | eu_operand1; // OR
|
||||
assign eu_alu6 = eu_operand0 ^ eu_operand1; // XOR
|
||||
assign eu_alu7 = { 1'b0 , eu_operand0[15:1] }; // SHR
|
||||
assign eu_alu2 = adder_out; // ADD
|
||||
assign eu_alu3 = { eu_operand0[7:0] , eu_operand0[15:8] }; // BYTESWAP
|
||||
assign eu_alu4 = eu_operand0 & eu_operand1; // AND
|
||||
assign eu_alu5 = eu_operand0 | eu_operand1; // OR
|
||||
assign eu_alu6 = eu_operand0 ^ eu_operand1; // XOR
|
||||
assign eu_alu7 = { 1'b0 , eu_operand0[15:1] }; // SHR
|
||||
|
||||
|
||||
|
||||
|
@ -281,7 +303,7 @@ assign eu_alu_out = (eu_opcode_type==3'h2) ? eu_alu2 :
|
|||
(eu_opcode_type==3'h7) ? eu_alu7 :
|
||||
20'hEEEEE;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -291,8 +313,8 @@ genvar i;
|
|||
generate
|
||||
for (i=0; i < 16; i=i+1)
|
||||
begin : GEN_ADDER
|
||||
assign adder_out[i] = eu_operand0[i] ^ eu_operand1[i] ^ carry[i];
|
||||
assign carry[i+1] = (eu_operand0[i] & eu_operand1[i]) | (eu_operand0[i] & carry[i]) | (eu_operand1[i] & carry[i]);
|
||||
assign adder_out[i] = eu_operand0[i] ^ eu_operand1[i] ^ carry[i];
|
||||
assign carry[i+1] = (eu_operand0[i] & eu_operand1[i]) | (eu_operand0[i] & carry[i]) | (eu_operand1[i] & carry[i]);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
|
@ -304,9 +326,9 @@ assign eu_biu_req = eu_biu_command[9];
|
|||
assign intr_asserted = BIU_INTR & intr_enable_delayed;
|
||||
|
||||
|
||||
assign new_instruction = (eu_rom_address[12:8]==5'h01) ? 1'b1 : 1'b0;
|
||||
assign new_instruction = (eu_rom_address[12:8]==5'h01) ? 1'b1 : 1'b0;
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
//
|
||||
// EU Microsequencer
|
||||
|
@ -348,117 +370,117 @@ begin : EU_MICROSEQUENCER
|
|||
eu_stall_pipeline <= 'h0;
|
||||
eu_rom_address <= 13'h0020;
|
||||
eu_calling_address <= 'h0;
|
||||
intr_enable_delayed <= 1'b0;
|
||||
intr_enable_delayed <= 1'b0;
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
|
||||
// Delay the INTR enable flag until after the next instruction begins.
|
||||
// No delay when it is disabled.
|
||||
if (eu_flag_i==1'b0)
|
||||
begin
|
||||
intr_enable_delayed <= 1'b0;
|
||||
end
|
||||
// No delay when it is disabled.
|
||||
if (eu_flag_i==1'b0)
|
||||
begin
|
||||
intr_enable_delayed <= 1'b0;
|
||||
end
|
||||
else
|
||||
if (new_instruction==1'b1)
|
||||
begin
|
||||
intr_enable_delayed <= eu_flag_i;
|
||||
end
|
||||
|
||||
if (new_instruction==1'b1)
|
||||
begin
|
||||
intr_enable_delayed <= eu_flag_i;
|
||||
end
|
||||
|
||||
// Latch the TF flag on its rising edge.
|
||||
eu_flag_t_d <= eu_flag_t;
|
||||
if (eu_flag_t_d==1'b0 && eu_flag_t==1'b1)
|
||||
begin
|
||||
eu_tr_latched <= 1'b1;
|
||||
eu_flag_t_d <= eu_flag_t;
|
||||
if (eu_flag_t_d==1'b0 && eu_flag_t==1'b1)
|
||||
begin
|
||||
eu_tr_latched <= 1'b1;
|
||||
end
|
||||
else if (eu_tf_debounce==1'b1)
|
||||
begin
|
||||
eu_tr_latched <= 1'b0;
|
||||
else if (eu_tf_debounce==1'b1)
|
||||
begin
|
||||
eu_tr_latched <= 1'b0;
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Latch the done bit from the biu.
|
||||
// Debounce it when the request is released.
|
||||
// Debounce it when the request is released.
|
||||
biu_done_d1 <= BIU_DONE;
|
||||
biu_done_d2 <= biu_done_d1;
|
||||
eu_biu_req_d1 <= eu_biu_req;
|
||||
if (biu_done_d2==1'b0 && biu_done_d1==1'b1)
|
||||
biu_done_caught <= 1'b1;
|
||||
else if (eu_biu_req_d1==1'b1 && eu_biu_req==1'b0)
|
||||
biu_done_caught <= 1'b0;
|
||||
|
||||
biu_done_d2 <= biu_done_d1;
|
||||
eu_biu_req_d1 <= eu_biu_req;
|
||||
if (biu_done_d2==1'b0 && biu_done_d1==1'b1)
|
||||
biu_done_caught <= 1'b1;
|
||||
else if (eu_biu_req_d1==1'b1 && eu_biu_req==1'b0)
|
||||
biu_done_caught <= 1'b0;
|
||||
|
||||
|
||||
|
||||
// Generate and store flags for addition
|
||||
if (eu_stall_pipeline==1'b0 && eu_opcode_type==3'h2)
|
||||
begin
|
||||
eu_add_carry <= carry[16];
|
||||
eu_add_carry8 <= carry[8];
|
||||
eu_add_aux_carry <= carry[4];
|
||||
eu_add_overflow16 <= carry[16] ^ carry[15];
|
||||
eu_add_overflow8 <= carry[8] ^ carry[7];
|
||||
|
||||
// Generate and store flags for addition
|
||||
if (eu_stall_pipeline==1'b0 && eu_opcode_type==3'h2)
|
||||
begin
|
||||
eu_add_carry <= carry[16];
|
||||
eu_add_carry8 <= carry[8];
|
||||
eu_add_aux_carry <= carry[4];
|
||||
eu_add_overflow16 <= carry[16] ^ carry[15];
|
||||
eu_add_overflow8 <= carry[8] ^ carry[7];
|
||||
end
|
||||
|
||||
|
||||
// Register writeback
|
||||
|
||||
// Register writeback
|
||||
if (eu_stall_pipeline==1'b0 && eu_opcode_type!=3'h0 && eu_opcode_type!=3'h1)
|
||||
begin
|
||||
eu_alu_last_result <= eu_alu_out[15:0];
|
||||
case (eu_opcode_dst_sel) // synthesis parallel_case
|
||||
4'h0 : eu_register_ax <= eu_alu_out[15:0];
|
||||
4'h1 : eu_register_bx <= eu_alu_out[15:0];
|
||||
4'h2 : eu_register_cx <= eu_alu_out[15:0];
|
||||
4'h3 : eu_register_dx <= eu_alu_out[15:0];
|
||||
4'h4 : eu_register_sp <= eu_alu_out[15:0];
|
||||
4'h5 : eu_register_bp <= eu_alu_out[15:0];
|
||||
4'h6 : eu_register_si <= eu_alu_out[15:0];
|
||||
4'h7 : eu_register_di <= eu_alu_out[15:0];
|
||||
4'h8 : eu_flags <= eu_alu_out[15:0];
|
||||
4'h9 : eu_register_r0 <= eu_alu_out[15:0];
|
||||
4'hA : eu_register_r1 <= eu_alu_out[15:0];
|
||||
4'hB : eu_register_r2 <= eu_alu_out[15:0];
|
||||
4'hC : eu_register_r3 <= eu_alu_out[15:0];
|
||||
4'hD : eu_biu_command <= eu_alu_out[15:0];
|
||||
//4'hE : ;
|
||||
4'hF : eu_biu_dataout <= eu_alu_out[15:0];
|
||||
default : ;
|
||||
endcase
|
||||
begin
|
||||
eu_alu_last_result <= eu_alu_out[15:0];
|
||||
case (eu_opcode_dst_sel) // synthesis parallel_case
|
||||
4'h0 : eu_register_ax <= eu_alu_out[15:0];
|
||||
4'h1 : eu_register_bx <= eu_alu_out[15:0];
|
||||
4'h2 : eu_register_cx <= eu_alu_out[15:0];
|
||||
4'h3 : eu_register_dx <= eu_alu_out[15:0];
|
||||
4'h4 : eu_register_sp <= eu_alu_out[15:0];
|
||||
4'h5 : eu_register_bp <= eu_alu_out[15:0];
|
||||
4'h6 : eu_register_si <= eu_alu_out[15:0];
|
||||
4'h7 : eu_register_di <= eu_alu_out[15:0];
|
||||
4'h8 : eu_flags <= eu_alu_out[15:0];
|
||||
4'h9 : eu_register_r0 <= eu_alu_out[15:0];
|
||||
4'hA : eu_register_r1 <= eu_alu_out[15:0];
|
||||
4'hB : eu_register_r2 <= eu_alu_out[15:0];
|
||||
4'hC : eu_register_r3 <= eu_alu_out[15:0];
|
||||
4'hD : eu_biu_command <= eu_alu_out[15:0];
|
||||
//4'hE : ;
|
||||
4'hF : eu_biu_dataout <= eu_alu_out[15:0];
|
||||
default : ;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
// JUMP Opcode
|
||||
if (eu_stall_pipeline==1'b0 && eu_opcode_type==3'h1 && eu_jump_boolean==1'b1)
|
||||
begin
|
||||
eu_stall_pipeline <= 1'b1;
|
||||
|
||||
// For subroutine CALLs, store next opcode address
|
||||
if (eu_opcode_jump_call==1'b1)
|
||||
begin
|
||||
eu_calling_address[51:0] <= {eu_calling_address[38:0] , eu_rom_address[12:0] }; // 4 deep calling addresses
|
||||
end
|
||||
// JUMP Opcode
|
||||
if (eu_stall_pipeline==1'b0 && eu_opcode_type==3'h1 && eu_jump_boolean==1'b1)
|
||||
begin
|
||||
eu_stall_pipeline <= 1'b1;
|
||||
|
||||
// For subroutine CALLs, store next opcode address
|
||||
if (eu_opcode_jump_call==1'b1)
|
||||
begin
|
||||
eu_calling_address[51:0] <= {eu_calling_address[38:0] , eu_rom_address[12:0] }; // 4 deep calling addresses
|
||||
end
|
||||
|
||||
case (eu_opcode_jump_src) // synthesis parallel_case
|
||||
3'h0 : eu_rom_address <= eu_opcode_immediate[12:0];
|
||||
3'h1 : eu_rom_address <= { 4'b0 , 1'b1 , PFQ_TOP_BYTE }; // If only used for primary opcode jump, maybe make fixed prepend rather than immediate value prepend?
|
||||
3'h2 : eu_rom_address <= { eu_opcode_immediate[4:0], PFQ_TOP_BYTE[7:6] , PFQ_TOP_BYTE[2:0] , 3'b000 }; // Rearranged mod_reg_rm byte - imm,MOD,RM,000
|
||||
3'h3 : begin
|
||||
eu_rom_address <= eu_calling_address[12:0];
|
||||
eu_calling_address[38:0] <= eu_calling_address[51:13];
|
||||
end
|
||||
3'h4 : eu_rom_address <= { eu_opcode_immediate[7:0], eu_biu_dataout[3:0] , 1'b0 }; // Jump table for EA register fetch decoding. Jump Addresses decoded from biu_dataout.
|
||||
3'h5 : eu_rom_address <= { eu_opcode_immediate[6:0], eu_biu_dataout[3:0] , 2'b00 }; // Jump table for EA register writeback decoding. Jump Addresses decoded from biu_dataout.
|
||||
3'h6 : eu_rom_address <= { eu_opcode_immediate[12:3], eu_biu_dataout[5:3] }; // Jump table for instructions that share same opcode and decode using the REG field.
|
||||
|
||||
default : ;
|
||||
endcase
|
||||
end
|
||||
|
||||
case (eu_opcode_jump_src) // synthesis parallel_case
|
||||
3'h0 : eu_rom_address <= eu_opcode_immediate[12:0];
|
||||
3'h1 : eu_rom_address <= { 4'b0 , 1'b1 , PFQ_TOP_BYTE }; // If only used for primary opcode jump, maybe make fixed prepend rather than immediate value prepend?
|
||||
3'h2 : eu_rom_address <= { eu_opcode_immediate[4:0], PFQ_TOP_BYTE[7:6] , PFQ_TOP_BYTE[2:0] , 3'b000 }; // Rearranged mod_reg_rm byte - imm,MOD,RM,000
|
||||
3'h3 : begin
|
||||
eu_rom_address <= eu_calling_address[12:0];
|
||||
eu_calling_address[38:0] <= eu_calling_address[51:13];
|
||||
end
|
||||
3'h4 : eu_rom_address <= { eu_opcode_immediate[7:0], eu_biu_dataout[3:0] , 1'b0 }; // Jump table for EA register fetch decoding. Jump Addresses decoded from biu_dataout.
|
||||
3'h5 : eu_rom_address <= { eu_opcode_immediate[6:0], eu_biu_dataout[3:0] , 2'b00 }; // Jump table for EA register writeback decoding. Jump Addresses decoded from biu_dataout.
|
||||
3'h6 : eu_rom_address <= { eu_opcode_immediate[12:3], eu_biu_dataout[5:3] }; // Jump table for instructions that share same opcode and decode using the REG field.
|
||||
|
||||
default : ;
|
||||
endcase
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
eu_stall_pipeline <= 1'b0; // Debounce the pipeline stall
|
||||
eu_rom_address <= eu_rom_address + 1'b1;
|
||||
eu_stall_pipeline <= 1'b0; // Debounce the pipeline stall
|
||||
eu_rom_address <= eu_rom_address + 1'b1;
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -14,16 +14,28 @@
|
|||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 2018 by Ted Fried info@MicroCoreLabs.com
|
||||
// Copyright (c) 2020 Ted Fried
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software and its
|
||||
// documentation for any purpose and without fee is hereby granted, provided
|
||||
// that the above copyright notice appear in all copies and that both that
|
||||
// copyright notice and this permission notice appear in supporting documentation.
|
||||
// This software is provided "as is" without express or implied warranty.
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
// Modification History:
|
||||
// =====================
|
||||
//
|
||||
|
@ -36,14 +48,14 @@
|
|||
|
||||
module MCLR5
|
||||
(
|
||||
input CORE_CLK,
|
||||
input RST_n,
|
||||
input CORE_CLK,
|
||||
input RST_n,
|
||||
|
||||
output [31:0] LOAD_STORE_ADDRESS,
|
||||
output [31:0] STORE_DATA,
|
||||
input [31:0] LOAD_DATA,
|
||||
output LOAD_REQ,
|
||||
output STORE_REQ
|
||||
output [31:0] LOAD_STORE_ADDRESS,
|
||||
output [31:0] STORE_DATA,
|
||||
input [31:0] LOAD_DATA,
|
||||
output LOAD_REQ,
|
||||
output STORE_REQ
|
||||
|
||||
);
|
||||
|
||||
|
@ -119,31 +131,31 @@ wire [4:0] alu3_opcode_rd;
|
|||
|
||||
/*
|
||||
// For Xilinx FPGAs
|
||||
DPROM_8Kx128 code_rom
|
||||
DPROM_8Kx128 code_rom
|
||||
(
|
||||
.clka (CORE_CLK),
|
||||
.addra (new_pc[14:2]),
|
||||
.douta (program_rom_data[127:0]),
|
||||
.clka (CORE_CLK),
|
||||
.addra (new_pc[14:2]),
|
||||
.douta (program_rom_data[127:0]),
|
||||
|
||||
.clkb (CORE_CLK),
|
||||
.addrb (new_pc_plus1[14:2]),
|
||||
.doutb (program_rom_data[255:128])
|
||||
.clkb (CORE_CLK),
|
||||
.addrb (new_pc_plus1[14:2]),
|
||||
.doutb (program_rom_data[255:128])
|
||||
);
|
||||
|
||||
*/
|
||||
|
||||
DPROM_8Kx128 code_rom (
|
||||
.address_a (new_pc[14:2]), // input, width = 13, ram_input.address_a
|
||||
.address_b (new_pc_plus1[14:2]), // input, width = 13, .address_b
|
||||
.clock (CORE_CLK), // input, width = 1, .clock
|
||||
.q_a (program_rom_data[127:0]), // output, width = 128, ram_output.q_a
|
||||
.q_b (program_rom_data[255:128]) // output, width = 128, .q_b
|
||||
);
|
||||
DPROM_8Kx128 code_rom (
|
||||
.address_a (new_pc[14:2]), // input, width = 13, ram_input.address_a
|
||||
.address_b (new_pc_plus1[14:2]), // input, width = 13, .address_b
|
||||
.clock (CORE_CLK), // input, width = 1, .clock
|
||||
.q_a (program_rom_data[127:0]), // output, width = 128, ram_output.q_a
|
||||
.q_b (program_rom_data[255:128]) // output, width = 128, .q_b
|
||||
);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
assign new_pc_plus1 = new_pc + 3'h4;
|
||||
|
||||
|
@ -158,25 +170,25 @@ assign alu3_pc = new_pc + 3;
|
|||
assign alu0_opcode = (new_pc[1:0]==2'h0) ? program_rom_data[31:0] :
|
||||
(new_pc[1:0]==2'h1) ? program_rom_data[63:32] :
|
||||
(new_pc[1:0]==2'h2) ? program_rom_data[95:64] :
|
||||
program_rom_data[127:96] ;
|
||||
program_rom_data[127:96] ;
|
||||
|
||||
|
||||
assign alu1_opcode = (new_pc[1:0]==2'h0) ? program_rom_data[63:32] :
|
||||
(new_pc[1:0]==2'h1) ? program_rom_data[95:64] :
|
||||
(new_pc[1:0]==2'h2) ? program_rom_data[127:96] :
|
||||
(new_pc[1:0]==2'h2) ? program_rom_data[127:96] :
|
||||
program_rom_data[159:128] ;
|
||||
|
||||
|
||||
assign alu2_opcode = (new_pc[1:0]==2'h0) ? program_rom_data[95:64] :
|
||||
(new_pc[1:0]==2'h1) ? program_rom_data[127:96] :
|
||||
(new_pc[1:0]==2'h1) ? program_rom_data[127:96] :
|
||||
(new_pc[1:0]==2'h2) ? program_rom_data[159:128] :
|
||||
program_rom_data[191:160] ;
|
||||
|
||||
program_rom_data[191:160] ;
|
||||
|
||||
assign alu3_opcode = (new_pc[1:0]==2'h0) ? program_rom_data[127:96] :
|
||||
(new_pc[1:0]==2'h1) ? program_rom_data[159:128] :
|
||||
(new_pc[1:0]==2'h2) ? program_rom_data[191:160] :
|
||||
program_rom_data[223:192] ;
|
||||
|
||||
|
||||
(new_pc[1:0]==2'h2) ? program_rom_data[191:160] :
|
||||
program_rom_data[223:192] ;
|
||||
|
||||
|
||||
|
||||
// Register decodes from the opcode
|
||||
//
|
||||
|
@ -214,7 +226,7 @@ assign alu0_rs1 = (alu0_opcode_rs1 == 5'h00) ? 32'h0 :
|
|||
(alu0_opcode_rs1 == 5'h01) ? register_1 :
|
||||
(alu0_opcode_rs1 == 5'h02) ? register_2 :
|
||||
(alu0_opcode_rs1 == 5'h03) ? register_3 :
|
||||
register_4 ;
|
||||
register_4 ;
|
||||
|
||||
|
||||
|
||||
|
@ -222,53 +234,53 @@ assign alu0_rs2 = (alu0_opcode_rs2 == 5'h00) ? 32'h0 :
|
|||
(alu0_opcode_rs2 == 5'h01) ? register_1 :
|
||||
(alu0_opcode_rs2 == 5'h02) ? register_2 :
|
||||
(alu0_opcode_rs2 == 5'h03) ? register_3 :
|
||||
register_4 ;
|
||||
register_4 ;
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
assign alu1_rs1 = ( alu0_rd[32]==1'b1 && (alu1_opcode_rs1==alu0_opcode_rd) ) ? alu0_rd[31:0] :
|
||||
(alu1_opcode_rs1 == 5'h00) ? 32'h0 :
|
||||
(alu1_opcode_rs1 == 5'h01) ? register_1 :
|
||||
(alu1_opcode_rs1 == 5'h02) ? register_2 :
|
||||
(alu1_opcode_rs1 == 5'h03) ? register_3 :
|
||||
register_4 ;
|
||||
|
||||
|
||||
|
||||
register_4 ;
|
||||
|
||||
|
||||
|
||||
assign alu1_rs2 = ( alu0_rd[32]==1'b1 && (alu1_opcode_rs2==alu0_opcode_rd) ) ? alu0_rd[31:0] :
|
||||
(alu1_opcode_rs2 == 5'h00) ? 32'h0 :
|
||||
(alu1_opcode_rs2 == 5'h01) ? register_1 :
|
||||
(alu1_opcode_rs2 == 5'h02) ? register_2 :
|
||||
(alu1_opcode_rs2 == 5'h03) ? register_3 :
|
||||
register_4 ;
|
||||
|
||||
register_4 ;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
assign alu2_rs1 = ( alu1_rd[32]==1'b1 && (alu2_opcode_rs1==alu1_opcode_rd) ) ? alu1_rd[31:0] :
|
||||
( alu0_rd[32]==1'b1 && (alu2_opcode_rs1==alu0_opcode_rd) ) ? alu0_rd[31:0] :
|
||||
(alu2_opcode_rs1 == 5'h00) ? 32'h0 :
|
||||
(alu2_opcode_rs1 == 5'h01) ? register_1 :
|
||||
(alu2_opcode_rs1 == 5'h02) ? register_2 :
|
||||
(alu2_opcode_rs1 == 5'h03) ? register_3 :
|
||||
register_4 ;
|
||||
|
||||
|
||||
|
||||
|
||||
register_4 ;
|
||||
|
||||
|
||||
|
||||
|
||||
assign alu2_rs2 = ( alu1_rd[32]==1'b1 && (alu2_opcode_rs2==alu1_opcode_rd) ) ? alu1_rd[31:0] :
|
||||
( alu0_rd[32]==1'b1 && (alu2_opcode_rs2==alu0_opcode_rd) ) ? alu0_rd[31:0] :
|
||||
(alu2_opcode_rs2 == 5'h00) ? 32'h0 :
|
||||
(alu2_opcode_rs2 == 5'h01) ? register_1 :
|
||||
(alu2_opcode_rs2 == 5'h02) ? register_2 :
|
||||
(alu2_opcode_rs2 == 5'h03) ? register_3 :
|
||||
register_4 ;
|
||||
|
||||
register_4 ;
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
|
||||
assign alu3_rs1 = ( alu2_rd[32]==1'b1 && (alu3_opcode_rs1==alu2_opcode_rd) ) ? alu2_rd[31:0] :
|
||||
( alu1_rd[32]==1'b1 && (alu3_opcode_rs1==alu1_opcode_rd) ) ? alu1_rd[31:0] :
|
||||
( alu0_rd[32]==1'b1 && (alu3_opcode_rs1==alu0_opcode_rd) ) ? alu0_rd[31:0] :
|
||||
|
@ -276,11 +288,11 @@ assign alu3_rs1 = ( alu2_rd[32]==1'b1 && (alu3_opcode_rs1==alu2_opcode_rd) ) ? a
|
|||
(alu3_opcode_rs1 == 5'h01) ? register_1 :
|
||||
(alu3_opcode_rs1 == 5'h02) ? register_2 :
|
||||
(alu3_opcode_rs1 == 5'h03) ? register_3 :
|
||||
register_4 ;
|
||||
|
||||
|
||||
|
||||
|
||||
register_4 ;
|
||||
|
||||
|
||||
|
||||
|
||||
assign alu3_rs2 = ( alu2_rd[32]==1'b1 && (alu3_opcode_rs2==alu2_opcode_rd) ) ? alu2_rd[31:0] :
|
||||
( alu1_rd[32]==1'b1 && (alu3_opcode_rs2==alu1_opcode_rd) ) ? alu1_rd[31:0] :
|
||||
( alu0_rd[32]==1'b1 && (alu3_opcode_rs2==alu0_opcode_rd) ) ? alu0_rd[31:0] :
|
||||
|
@ -288,11 +300,11 @@ assign alu3_rs2 = ( alu2_rd[32]==1'b1 && (alu3_opcode_rs2==alu2_opcode_rd) ) ? a
|
|||
(alu3_opcode_rs2 == 5'h01) ? register_1 :
|
||||
(alu3_opcode_rs2 == 5'h02) ? register_2 :
|
||||
(alu3_opcode_rs2 == 5'h03) ? register_3 :
|
||||
register_4 ;
|
||||
|
||||
|
||||
register_4 ;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------------------------
|
||||
//
|
||||
// Register writebacks
|
||||
|
@ -305,73 +317,73 @@ begin : REGISTER_WRITEBACKS
|
|||
if (RST_n==1'b0)
|
||||
begin
|
||||
alu0_load_req_d <= 'h0;
|
||||
new_pc <= 32'hFFFF_FFFC;
|
||||
new_pc <= 32'hFFFF_FFFC;
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
|
||||
|
||||
if ( (loadstore_stall == 4'b0000 && (alu0_load_req==1'b1 || alu0_store_req==1'b1) ) ||
|
||||
(loadstore_stall == 4'b0000 && (alu1_load_req==1'b1 || alu1_store_req==1'b1) ) ||
|
||||
(loadstore_stall == 4'b0000 && (alu2_load_req==1'b1 || alu2_store_req==1'b1) ) ||
|
||||
(loadstore_stall == 4'b0000 && (alu3_load_req==1'b1 || alu3_store_req==1'b1) ) )
|
||||
begin
|
||||
loadstore_stall <= 4'b1111; // new_pc_stall for three cycles
|
||||
(loadstore_stall == 4'b0000 && (alu3_load_req==1'b1 || alu3_store_req==1'b1) ) )
|
||||
begin
|
||||
loadstore_stall <= 4'b1111; // new_pc_stall for three cycles
|
||||
end
|
||||
else
|
||||
begin
|
||||
loadstore_stall <= { 1'b0 , loadstore_stall[3:1] };
|
||||
else
|
||||
begin
|
||||
loadstore_stall <= { 1'b0 , loadstore_stall[3:1] };
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// Writeback register file
|
||||
// Only write back registers that have been updated.
|
||||
// Block register updates if a previous alu is taking a branch
|
||||
//
|
||||
if (new_pc_stall==1'b0 && ((loadstore_stall==4'b0001 || alu0_newpc[32]==1'b0) && alu1_newpc[32]==1'b0 && alu2_newpc[32]==1'b0) && alu3_rd[32]==1'b1)
|
||||
begin
|
||||
case (alu3_opcode_rd)
|
||||
5'h01 : register_1 <= alu3_rd[31:0];
|
||||
5'h02 : register_2 <= alu3_rd[31:0];
|
||||
5'h03 : register_3 <= alu3_rd[31:0];
|
||||
5'h04 : register_4 <= alu3_rd[31:0];
|
||||
default: ;
|
||||
case (alu3_opcode_rd)
|
||||
5'h01 : register_1 <= alu3_rd[31:0];
|
||||
5'h02 : register_2 <= alu3_rd[31:0];
|
||||
5'h03 : register_3 <= alu3_rd[31:0];
|
||||
5'h04 : register_4 <= alu3_rd[31:0];
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
else if (new_pc_stall==1'b0 && ((loadstore_stall==4'b0001 || alu0_newpc[32]==1'b0) && alu1_newpc[32]==1'b0) && alu2_rd[32]==1'b1)
|
||||
begin
|
||||
case (alu2_opcode_rd)
|
||||
5'h01 : register_1 <= alu2_rd[31:0];
|
||||
5'h02 : register_2 <= alu2_rd[31:0];
|
||||
5'h03 : register_3 <= alu2_rd[31:0];
|
||||
5'h04 : register_4 <= alu2_rd[31:0];
|
||||
default: ;
|
||||
case (alu2_opcode_rd)
|
||||
5'h01 : register_1 <= alu2_rd[31:0];
|
||||
5'h02 : register_2 <= alu2_rd[31:0];
|
||||
5'h03 : register_3 <= alu2_rd[31:0];
|
||||
5'h04 : register_4 <= alu2_rd[31:0];
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
else if (new_pc_stall==1'b0 && (loadstore_stall==4'b0001 || alu0_newpc[32]==1'b0) && alu1_rd[32]==1'b1)
|
||||
begin
|
||||
case (alu1_opcode_rd)
|
||||
5'h01 : register_1 <= alu1_rd[31:0];
|
||||
5'h02 : register_2 <= alu1_rd[31:0];
|
||||
5'h03 : register_3 <= alu1_rd[31:0];
|
||||
5'h04 : register_4 <= alu1_rd[31:0];
|
||||
default: ;
|
||||
case (alu1_opcode_rd)
|
||||
5'h01 : register_1 <= alu1_rd[31:0];
|
||||
5'h02 : register_2 <= alu1_rd[31:0];
|
||||
5'h03 : register_3 <= alu1_rd[31:0];
|
||||
5'h04 : register_4 <= alu1_rd[31:0];
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
else if (new_pc_stall==1'b0 && alu0_rd[32]==1'b1)
|
||||
begin
|
||||
case (alu0_opcode_rd)
|
||||
5'h01 : register_1 <= alu0_rd[31:0];
|
||||
5'h02 : register_2 <= alu0_rd[31:0];
|
||||
5'h03 : register_3 <= alu0_rd[31:0];
|
||||
5'h04 : register_4 <= alu0_rd[31:0];
|
||||
default: ;
|
||||
case (alu0_opcode_rd)
|
||||
5'h01 : register_1 <= alu0_rd[31:0];
|
||||
5'h02 : register_2 <= alu0_rd[31:0];
|
||||
5'h03 : register_3 <= alu0_rd[31:0];
|
||||
5'h04 : register_4 <= alu0_rd[31:0];
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
@ -383,33 +395,33 @@ else
|
|||
|
||||
if ((new_pc_stall==1'b0 && alu0_newpc[32]==1'b1) && loadstore_stall!=4'b0001)
|
||||
begin
|
||||
new_pc_stall <= 1'b1;
|
||||
new_pc <= alu0_newpc[31:0];
|
||||
end
|
||||
|
||||
new_pc_stall <= 1'b1;
|
||||
new_pc <= alu0_newpc[31:0];
|
||||
end
|
||||
|
||||
else if (new_pc_stall==1'b0 && alu1_newpc[32]==1'b1)
|
||||
begin
|
||||
new_pc_stall <= 1'b1;
|
||||
new_pc <= alu1_newpc[31:0];
|
||||
end
|
||||
|
||||
new_pc_stall <= 1'b1;
|
||||
new_pc <= alu1_newpc[31:0];
|
||||
end
|
||||
|
||||
else if (new_pc_stall==1'b0 && alu2_newpc[32]==1'b1)
|
||||
begin
|
||||
new_pc_stall <= 1'b1;
|
||||
new_pc <= alu2_newpc[31:0];
|
||||
end
|
||||
|
||||
new_pc_stall <= 1'b1;
|
||||
new_pc <= alu2_newpc[31:0];
|
||||
end
|
||||
|
||||
else if (new_pc_stall==1'b0 && alu3_newpc[32]==1'b1)
|
||||
begin
|
||||
new_pc_stall <= 1'b1;
|
||||
new_pc <= alu3_newpc[31:0];
|
||||
end
|
||||
|
||||
new_pc_stall <= 1'b1;
|
||||
new_pc <= alu3_newpc[31:0];
|
||||
end
|
||||
|
||||
else
|
||||
begin
|
||||
new_pc <= new_pc + 32'h0000_0004;
|
||||
new_pc_stall <= 1'b0;
|
||||
end
|
||||
begin
|
||||
new_pc <= new_pc + 32'h0000_0004;
|
||||
new_pc_stall <= 1'b0;
|
||||
end
|
||||
|
||||
end
|
||||
end // Register writebacks
|
||||
|
@ -422,68 +434,68 @@ end // Register writebacks
|
|||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
MCLR5_alu mclr5_alu0
|
||||
MCLR5_alu mclr5_alu0
|
||||
(
|
||||
.OPCODE (alu0_opcode),
|
||||
.PC (alu0_pc),
|
||||
.RS1 (alu0_rs1),
|
||||
.RS2 (alu0_rs2),
|
||||
.RD (alu0_rd),
|
||||
.NEWPC (alu0_newpc),
|
||||
.LOAD_DATA (alu0_load_data),
|
||||
.STORE_DATA (alu0_store_data),
|
||||
.LOAD_REQ (alu0_load_req),
|
||||
.STORE_REQ (alu0_store_req),
|
||||
.LOAD_STORE_ADDRESS (alu0_load_store_address)
|
||||
.OPCODE (alu0_opcode),
|
||||
.PC (alu0_pc),
|
||||
.RS1 (alu0_rs1),
|
||||
.RS2 (alu0_rs2),
|
||||
.RD (alu0_rd),
|
||||
.NEWPC (alu0_newpc),
|
||||
.LOAD_DATA (alu0_load_data),
|
||||
.STORE_DATA (alu0_store_data),
|
||||
.LOAD_REQ (alu0_load_req),
|
||||
.STORE_REQ (alu0_store_req),
|
||||
.LOAD_STORE_ADDRESS (alu0_load_store_address)
|
||||
);
|
||||
|
||||
|
||||
MCLR5_alu mclr5_alu1
|
||||
MCLR5_alu mclr5_alu1
|
||||
(
|
||||
.OPCODE (alu1_opcode),
|
||||
.PC (alu1_pc),
|
||||
.RS1 (alu1_rs1),
|
||||
.RS2 (alu1_rs2),
|
||||
.RD (alu1_rd),
|
||||
.NEWPC (alu1_newpc),
|
||||
.LOAD_DATA (),
|
||||
.STORE_DATA (),
|
||||
.LOAD_REQ (alu1_load_req),
|
||||
.STORE_REQ (alu1_store_req),
|
||||
.LOAD_STORE_ADDRESS ()
|
||||
.OPCODE (alu1_opcode),
|
||||
.PC (alu1_pc),
|
||||
.RS1 (alu1_rs1),
|
||||
.RS2 (alu1_rs2),
|
||||
.RD (alu1_rd),
|
||||
.NEWPC (alu1_newpc),
|
||||
.LOAD_DATA (),
|
||||
.STORE_DATA (),
|
||||
.LOAD_REQ (alu1_load_req),
|
||||
.STORE_REQ (alu1_store_req),
|
||||
.LOAD_STORE_ADDRESS ()
|
||||
);
|
||||
|
||||
|
||||
MCLR5_alu mclr5_alu2
|
||||
MCLR5_alu mclr5_alu2
|
||||
(
|
||||
.OPCODE (alu2_opcode),
|
||||
.PC (alu2_pc),
|
||||
.RS1 (alu2_rs1),
|
||||
.RS2 (alu2_rs2),
|
||||
.RD (alu2_rd),
|
||||
.NEWPC (alu2_newpc),
|
||||
.LOAD_DATA (),
|
||||
.STORE_DATA (),
|
||||
.LOAD_REQ (alu2_load_req),
|
||||
.STORE_REQ (alu2_store_req),
|
||||
.LOAD_STORE_ADDRESS ()
|
||||
.OPCODE (alu2_opcode),
|
||||
.PC (alu2_pc),
|
||||
.RS1 (alu2_rs1),
|
||||
.RS2 (alu2_rs2),
|
||||
.RD (alu2_rd),
|
||||
.NEWPC (alu2_newpc),
|
||||
.LOAD_DATA (),
|
||||
.STORE_DATA (),
|
||||
.LOAD_REQ (alu2_load_req),
|
||||
.STORE_REQ (alu2_store_req),
|
||||
.LOAD_STORE_ADDRESS ()
|
||||
);
|
||||
|
||||
|
||||
|
||||
MCLR5_alu mclr5_alu3
|
||||
MCLR5_alu mclr5_alu3
|
||||
(
|
||||
.OPCODE (alu3_opcode),
|
||||
.PC (alu3_pc),
|
||||
.RS1 (alu3_rs1),
|
||||
.RS2 (alu3_rs2),
|
||||
.RD (alu3_rd),
|
||||
.NEWPC (alu3_newpc),
|
||||
.LOAD_DATA (),
|
||||
.STORE_DATA (),
|
||||
.LOAD_REQ (alu3_load_req),
|
||||
.STORE_REQ (alu3_store_req),
|
||||
.LOAD_STORE_ADDRESS ()
|
||||
.OPCODE (alu3_opcode),
|
||||
.PC (alu3_pc),
|
||||
.RS1 (alu3_rs1),
|
||||
.RS2 (alu3_rs2),
|
||||
.RD (alu3_rd),
|
||||
.NEWPC (alu3_newpc),
|
||||
.LOAD_DATA (),
|
||||
.STORE_DATA (),
|
||||
.LOAD_REQ (alu3_load_req),
|
||||
.STORE_REQ (alu3_store_req),
|
||||
.LOAD_STORE_ADDRESS ()
|
||||
);
|
||||
|
||||
|
||||
|
|
|
@ -14,16 +14,28 @@
|
|||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (C) 2018 by Ted Fried info@MicroCoreLabs.com
|
||||
// Copyright (c) 2020 Ted Fried
|
||||
//
|
||||
// Permission to use, copy, modify, and distribute this software and its
|
||||
// documentation for any purpose and without fee is hereby granted, provided
|
||||
// that the above copyright notice appear in all copies and that both that
|
||||
// copyright notice and this permission notice appear in supporting documentation.
|
||||
// This software is provided "as is" without express or implied warranty.
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
|
||||
// Modification History:
|
||||
// =====================
|
||||
//
|
||||
|
@ -115,9 +127,9 @@ assign bge_taken = ($signed(RS1) >= $signed(RS2)) ? 1'b1 : 1'b0;
|
|||
assign bltu_taken = (RS1 < RS2) ? 1'b1 : 1'b0;
|
||||
assign bgeu_taken = (RS1 >= RS2) ? 1'b1 : 1'b0;
|
||||
|
||||
|
||||
|
||||
assign pc_adjusted = PC - 4'h4; // Subtracts pipelined PC to the true PC
|
||||
|
||||
|
||||
assign STORE_DATA = RS2;
|
||||
|
||||
|
||||
|
@ -126,48 +138,48 @@ always @* begin
|
|||
|
||||
32'b???????_?????_?????_???_?????_01101?? : RD = { 1'b1 , {u_immediate[31:12] , 12'b0 } } ; // LUI
|
||||
32'b???????_?????_?????_???_?????_00101?? : RD = { 1'b1 , PC + {u_immediate[31:12] , 12'b0 } } ; // AUIPC
|
||||
32'b???????_?????_?????_???_?????_11011?? : RD = { 1'b1 , PC + 3'h4 } ; // JAL
|
||||
32'b???????_?????_?????_???_?????_11001?? : RD = { 1'b1 , PC + 3'h4 } ; // JALR
|
||||
32'b???????_?????_?????_000_?????_00100?? : RD = { 1'b1 , RS1 + i_immediate } ; // ADDI
|
||||
32'b???????_?????_?????_010_?????_00100?? : RD = { 1'b1 , slti_true } ; // SLTI
|
||||
32'b???????_?????_?????_011_?????_00100?? : RD = { 1'b1 , sltiu_true } ; // SLTIU
|
||||
32'b???????_?????_?????_100_?????_00100?? : RD = { 1'b1 , RS1 ^ i_immediate } ; // XORI
|
||||
32'b???????_?????_?????_110_?????_00100?? : RD = { 1'b1 , RS1 | i_immediate } ; // ORI
|
||||
32'b???????_?????_?????_111_?????_00100?? : RD = { 1'b1 , RS1 & i_immediate } ; // ANDI
|
||||
32'b???????_?????_?????_001_?????_00100?? : RD = { 1'b1 , slli_result } ; // SLLI
|
||||
32'b?0?????_?????_?????_101_?????_00100?? : RD = { 1'b1 , srli_result } ; // SRLI
|
||||
32'b?1?????_?????_?????_101_?????_00100?? : RD = { 1'b1 , srai_result } ; // SRAI
|
||||
32'b?0?????_?????_?????_000_?????_01100?? : RD = { 1'b1 , RS1 + RS2 } ; // ADD
|
||||
32'b?1?????_?????_?????_000_?????_01100?? : RD = { 1'b1 , RS1 - RS2 } ; // SUB
|
||||
32'b???????_?????_?????_001_?????_01100?? : RD = { 1'b1 , sll_result } ; // SLL
|
||||
32'b???????_?????_?????_010_?????_01100?? : RD = { 1'b1 , slt_true } ; // SLT
|
||||
32'b???????_?????_?????_011_?????_01100?? : RD = { 1'b1 , sltu_true } ; // SLTU
|
||||
32'b???????_?????_?????_100_?????_01100?? : RD = { 1'b1 , RS1 ^ RS2 } ; // XOR
|
||||
32'b?0?????_?????_?????_101_?????_01100?? : RD = { 1'b1 , srl_result } ; // SRL
|
||||
32'b?1?????_?????_?????_101_?????_01100?? : RD = { 1'b1 , sra_result } ; // SRA
|
||||
32'b???????_?????_?????_110_?????_01100?? : RD = { 1'b1 , RS1 | RS2 } ; // OR
|
||||
32'b???????_?????_?????_111_?????_01100?? : RD = { 1'b1 , RS1 & RS2 } ; // AND
|
||||
|
||||
32'b???????_?????_?????_010_?????_00000?? : RD = { 1'b1 , LOAD_DATA } ; // LW
|
||||
default : RD = { 1'b0 , 32'h0000_0000 } ;
|
||||
|
||||
32'b???????_?????_?????_???_?????_11011?? : RD = { 1'b1 , PC + 3'h4 } ; // JAL
|
||||
32'b???????_?????_?????_???_?????_11001?? : RD = { 1'b1 , PC + 3'h4 } ; // JALR
|
||||
32'b???????_?????_?????_000_?????_00100?? : RD = { 1'b1 , RS1 + i_immediate } ; // ADDI
|
||||
32'b???????_?????_?????_010_?????_00100?? : RD = { 1'b1 , slti_true } ; // SLTI
|
||||
32'b???????_?????_?????_011_?????_00100?? : RD = { 1'b1 , sltiu_true } ; // SLTIU
|
||||
32'b???????_?????_?????_100_?????_00100?? : RD = { 1'b1 , RS1 ^ i_immediate } ; // XORI
|
||||
32'b???????_?????_?????_110_?????_00100?? : RD = { 1'b1 , RS1 | i_immediate } ; // ORI
|
||||
32'b???????_?????_?????_111_?????_00100?? : RD = { 1'b1 , RS1 & i_immediate } ; // ANDI
|
||||
32'b???????_?????_?????_001_?????_00100?? : RD = { 1'b1 , slli_result } ; // SLLI
|
||||
32'b?0?????_?????_?????_101_?????_00100?? : RD = { 1'b1 , srli_result } ; // SRLI
|
||||
32'b?1?????_?????_?????_101_?????_00100?? : RD = { 1'b1 , srai_result } ; // SRAI
|
||||
32'b?0?????_?????_?????_000_?????_01100?? : RD = { 1'b1 , RS1 + RS2 } ; // ADD
|
||||
32'b?1?????_?????_?????_000_?????_01100?? : RD = { 1'b1 , RS1 - RS2 } ; // SUB
|
||||
32'b???????_?????_?????_001_?????_01100?? : RD = { 1'b1 , sll_result } ; // SLL
|
||||
32'b???????_?????_?????_010_?????_01100?? : RD = { 1'b1 , slt_true } ; // SLT
|
||||
32'b???????_?????_?????_011_?????_01100?? : RD = { 1'b1 , sltu_true } ; // SLTU
|
||||
32'b???????_?????_?????_100_?????_01100?? : RD = { 1'b1 , RS1 ^ RS2 } ; // XOR
|
||||
32'b?0?????_?????_?????_101_?????_01100?? : RD = { 1'b1 , srl_result } ; // SRL
|
||||
32'b?1?????_?????_?????_101_?????_01100?? : RD = { 1'b1 , sra_result } ; // SRA
|
||||
32'b???????_?????_?????_110_?????_01100?? : RD = { 1'b1 , RS1 | RS2 } ; // OR
|
||||
32'b???????_?????_?????_111_?????_01100?? : RD = { 1'b1 , RS1 & RS2 } ; // AND
|
||||
|
||||
32'b???????_?????_?????_010_?????_00000?? : RD = { 1'b1 , LOAD_DATA } ; // LW
|
||||
default : RD = { 1'b0 , 32'h0000_0000 } ;
|
||||
|
||||
endcase
|
||||
|
||||
|
||||
casex (OPCODE)
|
||||
|
||||
32'b???????_?????_?????_010_?????_00000?? : LOAD_STORE_ADDRESS = RS1 + i_immediate ; // Loads
|
||||
32'b???????_?????_?????_010_?????_01000?? : LOAD_STORE_ADDRESS = RS1 + s_immediate ; // Stores
|
||||
default : ;
|
||||
32'b???????_?????_?????_010_?????_00000?? : LOAD_STORE_ADDRESS = RS1 + i_immediate ; // Loads
|
||||
32'b???????_?????_?????_010_?????_01000?? : LOAD_STORE_ADDRESS = RS1 + s_immediate ; // Stores
|
||||
default : ;
|
||||
endcase
|
||||
|
||||
|
||||
casex (OPCODE)
|
||||
|
||||
32'b???????_?????_?????_010_?????_00000?? : LOAD_REQ = 1'b1 ;
|
||||
32'b???????_?????_?????_010_?????_01000?? : STORE_REQ = 1'b1 ;
|
||||
32'b???????_?????_?????_010_?????_01000?? : STORE_REQ = 1'b1 ;
|
||||
default : begin LOAD_REQ = 1'b0 ; STORE_REQ = 1'b0; end
|
||||
|
||||
|
||||
endcase
|
||||
|
||||
|
||||
|
@ -188,9 +200,9 @@ always @* begin
|
|||
32'b???????_?????_?????_110_?????_11000?? : if (bltu_taken == 1'b1) NEWPC = { 1'b1 , pc_adjusted + b_immediate } ; // BLTU
|
||||
32'b???????_?????_?????_111_?????_11000?? : if (bgeu_taken == 1'b1) NEWPC = { 1'b1 , pc_adjusted + b_immediate } ; // BGEU
|
||||
|
||||
|
||||
default : NEWPC = { 1'b0 , 32'h0000_0000 } ; // No Branch Taken
|
||||
|
||||
|
||||
default : NEWPC = { 1'b0 , 32'h0000_0000 } ; // No Branch Taken
|
||||
|
||||
endcase
|
||||
|
||||
|
||||
|
@ -199,7 +211,7 @@ always @* begin
|
|||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -20,6 +20,28 @@
|
|||
//
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2020 Ted Fried
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
|
@ -32,10 +54,10 @@ module mclwr1
|
|||
|
||||
output UART_TX,
|
||||
input UART_RX,
|
||||
|
||||
|
||||
output UART_TX2,
|
||||
input UART_RX2,
|
||||
|
||||
|
||||
output[8:0] SNOOP_OUT
|
||||
|
||||
);
|
||||
|
@ -277,14 +299,14 @@ assign ibm_byte =
|
|||
always @(posedge clk_int)
|
||||
begin
|
||||
|
||||
uart_rx_d <= UART_RX & UART_RX2; // Either of the two serial ports can send data
|
||||
uart_rx_d <= UART_RX & UART_RX2; // Either of the two serial ports can send data
|
||||
uart_rx_d1 <= uart_rx_d;
|
||||
uart_rx_d2 <= uart_rx_d1;
|
||||
|
||||
rx_count <= rx_count + 1'b1;
|
||||
|
||||
case (rx_count)
|
||||
16'h0000: if (uart_rx_d2!=1'b0) // Look for Start Bit
|
||||
16'h0000: if (uart_rx_d2!=1'b0) // Look for Start Bit
|
||||
begin
|
||||
rx_count <= 'h0;
|
||||
end
|
||||
|
|
|
@ -0,0 +1,578 @@
|
|||
//
|
||||
//
|
||||
// File Name : mclwr1.v
|
||||
// Author : Ted Fried, MicroCore Labs
|
||||
// Creation : 11/3/2019
|
||||
// Code Type : Synthesizable
|
||||
//
|
||||
// Description:
|
||||
// ============
|
||||
//
|
||||
// FPGA version of the Printer Option for the IBM Wheelwriter
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Version History:
|
||||
// ================
|
||||
//
|
||||
// Revision 1 11/3/19
|
||||
// Initial revision
|
||||
//
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
`timescale 1ns/100ps
|
||||
|
||||
|
||||
|
||||
module mclwr1
|
||||
(
|
||||
inout IBM_BUS,
|
||||
output BUFFER_DIR,
|
||||
|
||||
output UART_TX,
|
||||
input UART_RX,
|
||||
|
||||
output UART_TX2,
|
||||
input UART_RX2,
|
||||
|
||||
output[8:0] SNOOP_OUT
|
||||
|
||||
);
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
// Internal Signals
|
||||
reg rx_fifo_wr = 'h0;
|
||||
reg rx_fifo_rd = 'h0;
|
||||
reg tx_fifo_wr = 'h0;
|
||||
reg tx_fifo_rd = 'h0;
|
||||
reg ibm_clock = 'h0;
|
||||
reg ibm_load_tx = 'h0;
|
||||
reg ibm_clock_d = 'h0;
|
||||
reg uart_rx_d = 1'b1;
|
||||
reg uart_rx_d1 = 1'b1;
|
||||
reg uart_rx_d2 = 1'b1;
|
||||
reg uart_clock = 'h0;
|
||||
reg uart_clock_d = 'h0;
|
||||
reg ibm_bus_d = 1'b1;
|
||||
reg ibm_bus_d1 = 1'b1;
|
||||
reg ibm_bus_d2 = 1'b1;
|
||||
reg rx_fifo_almost_full_d ='h0;
|
||||
reg [8:0] uart_prescaler ='h0;
|
||||
reg [10:0] uart_tx_shiftout = 11'b11111111111;
|
||||
reg [15:0] rx_count = 'h0;
|
||||
reg [7:0] main_count = 'h0;
|
||||
reg [15:0] tx_bytes = 'h0;
|
||||
reg [15:0] ibm_count = 'h0;
|
||||
reg [7:0] prescaler = 'h0;
|
||||
reg [8:0] tx_fifo_data_in = 'h0;
|
||||
reg [9:0] ibm_shift_out = 10'b1111111111;
|
||||
reg [7:0] uart_rx_byte = 'h0;
|
||||
reg [15:0] snoop_count = 'h0;
|
||||
reg [8:0] snoop_byte = 9'b111111111;
|
||||
reg [8:0] snoop_byte_all = 9'b111111111;
|
||||
wire clk_int;
|
||||
wire tx_fifo_full;
|
||||
wire tx_fifo_empty;
|
||||
wire rx_fifo_full;
|
||||
wire rx_fifo_almost_full;
|
||||
wire rx_fifo_empty;
|
||||
wire [8:0] rx_fifo_data_out;
|
||||
wire [8:0] tx_fifo_data_out;
|
||||
wire [8:0] ibm_byte;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// OSCH - Internal clock oscillator for Lattice XO2
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
defparam OSCILLATOR_INST.NOM_FREQ = "2.22";
|
||||
OSCH OSCILLATOR_INST
|
||||
(
|
||||
.STDBY (1'b0),
|
||||
.OSC (clk_int),
|
||||
.SEDSTDBY ()
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// RX FIFO - Holds 1K characters from the UART
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
rx_fifo RX_FIFO
|
||||
(
|
||||
.Reset (1'b0 ),
|
||||
.RPReset (1'b0 ),
|
||||
|
||||
.WrClock (clk_int ),
|
||||
.Data (ibm_byte),
|
||||
.WrEn (rx_fifo_wr ),
|
||||
.Full (rx_fifo_full ),
|
||||
.AlmostFull (rx_fifo_almost_full ),
|
||||
|
||||
.RdClock (clk_int ),
|
||||
.Q (rx_fifo_data_out ),
|
||||
.RdEn (rx_fifo_rd),
|
||||
.Empty (rx_fifo_empty ),
|
||||
.AlmostEmpty( )
|
||||
);
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
// TX FIFO - Holds 1K commands to be sent to the IBM Wheelwriter
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
rx_fifo TX_FIFO
|
||||
(
|
||||
.Reset (1'b0 ),
|
||||
.RPReset (1'b0 ),
|
||||
|
||||
.WrClock (clk_int ),
|
||||
.Data (tx_fifo_data_in ),
|
||||
.WrEn (tx_fifo_wr ),
|
||||
.Full ( ),
|
||||
.AlmostFull ( ),
|
||||
|
||||
.RdClock (clk_int ),
|
||||
.Q (tx_fifo_data_out ),
|
||||
.RdEn (tx_fifo_rd),
|
||||
.Empty (tx_fifo_empty ),
|
||||
.AlmostEmpty( )
|
||||
);
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Combinationals
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
assign SNOOP_OUT = {8'h0 , rx_fifo_full, rx_fifo_almost_full };
|
||||
//assign SNOOP_OUT = snoop_byte_all;
|
||||
//assign SNOOP_OUT = rx_fifo_data_out[7:0];
|
||||
//assign SNOOP_OUT = uart_rx_byte[7:0];
|
||||
|
||||
assign UART_TX = uart_tx_shiftout[0];
|
||||
assign UART_TX2 = uart_tx_shiftout[0];
|
||||
|
||||
assign BUFFER_DIR = ~ibm_shift_out[0];
|
||||
|
||||
assign IBM_BUS = (ibm_shift_out[0]==1'b0) ? 1'b0 : 1'bZ; // open collector
|
||||
|
||||
assign ibm_byte =
|
||||
(uart_rx_byte==8'h0D) ? 9'h099 : // Carriage Return
|
||||
|
||||
(uart_rx_byte==8'h20) ? 9'h000 : // Space
|
||||
(uart_rx_byte==8'h21) ? 9'h049 : // !
|
||||
(uart_rx_byte==8'h22) ? 9'h04b : // "
|
||||
(uart_rx_byte==8'h23) ? 9'h038 : // #
|
||||
(uart_rx_byte==8'h24) ? 9'h037 : // $
|
||||
(uart_rx_byte==8'h25) ? 9'h039 : // %
|
||||
(uart_rx_byte==8'h26) ? 9'h03F : // &
|
||||
(uart_rx_byte==8'h27) ? 9'h04C : // `
|
||||
(uart_rx_byte==8'h28) ? 9'h023 : // (
|
||||
(uart_rx_byte==8'h29) ? 9'h016 : // )
|
||||
(uart_rx_byte==8'h2A) ? 9'h036 : // *
|
||||
(uart_rx_byte==8'h2B) ? 9'h03B : // +
|
||||
(uart_rx_byte==8'h2C) ? 9'h00C : // ,
|
||||
(uart_rx_byte==8'h2D) ? 9'h00E : // -
|
||||
(uart_rx_byte==8'h2E) ? 9'h057 : // .
|
||||
(uart_rx_byte==8'h2F) ? 9'h028 : // /
|
||||
|
||||
(uart_rx_byte==8'h30) ? 9'h030 : // 0
|
||||
(uart_rx_byte==8'h31) ? 9'h02E : // 1
|
||||
(uart_rx_byte==8'h32) ? 9'h02F : // 2
|
||||
(uart_rx_byte==8'h33) ? 9'h02C : // 3
|
||||
(uart_rx_byte==8'h34) ? 9'h032 : // 4
|
||||
(uart_rx_byte==8'h35) ? 9'h031 : // 5
|
||||
(uart_rx_byte==8'h36) ? 9'h033 : // 6
|
||||
(uart_rx_byte==8'h37) ? 9'h035 : // 7
|
||||
(uart_rx_byte==8'h38) ? 9'h034 : // 8
|
||||
(uart_rx_byte==8'h39) ? 9'h02A : // 9
|
||||
(uart_rx_byte==8'h3A) ? 9'h04E : // :
|
||||
(uart_rx_byte==8'h3B) ? 9'h050 : // ;
|
||||
// (uart_rx_byte==8'h3C) ? 9'h000 : // <
|
||||
(uart_rx_byte==8'h3D) ? 9'h04D : // =
|
||||
// (uart_rx_byte==8'h3E) ? 9'h000 : // >
|
||||
(uart_rx_byte==8'h3F) ? 9'h04A : // ?
|
||||
|
||||
(uart_rx_byte==8'h40) ? 9'h03D : // @
|
||||
(uart_rx_byte==8'h41) ? 9'h020 : // A
|
||||
(uart_rx_byte==8'h42) ? 9'h012 : // B
|
||||
(uart_rx_byte==8'h43) ? 9'h01B : // C
|
||||
(uart_rx_byte==8'h44) ? 9'h01D : // D
|
||||
(uart_rx_byte==8'h45) ? 9'h01E : // E
|
||||
(uart_rx_byte==8'h46) ? 9'h011 : // F
|
||||
(uart_rx_byte==8'h47) ? 9'h00F : // G
|
||||
(uart_rx_byte==8'h48) ? 9'h014 : // H
|
||||
(uart_rx_byte==8'h49) ? 9'h01F : // I
|
||||
(uart_rx_byte==8'h4A) ? 9'h021 : // J
|
||||
(uart_rx_byte==8'h4B) ? 9'h02B : // K
|
||||
(uart_rx_byte==8'h4C) ? 9'h018 : // L
|
||||
(uart_rx_byte==8'h4D) ? 9'h024 : // M
|
||||
(uart_rx_byte==8'h4E) ? 9'h01A : // N
|
||||
(uart_rx_byte==8'h4F) ? 9'h022 : // O
|
||||
|
||||
(uart_rx_byte==8'h50) ? 9'h015 : // P
|
||||
(uart_rx_byte==8'h51) ? 9'h03E : // Q
|
||||
(uart_rx_byte==8'h52) ? 9'h017 : // R
|
||||
(uart_rx_byte==8'h53) ? 9'h019 : // S
|
||||
(uart_rx_byte==8'h54) ? 9'h01C : // T
|
||||
(uart_rx_byte==8'h55) ? 9'h010 : // U
|
||||
(uart_rx_byte==8'h56) ? 9'h00D : // V
|
||||
(uart_rx_byte==8'h57) ? 9'h029 : // W
|
||||
(uart_rx_byte==8'h58) ? 9'h02D : // X
|
||||
(uart_rx_byte==8'h59) ? 9'h026 : // Y
|
||||
(uart_rx_byte==8'h5A) ? 9'h013 : // Z
|
||||
(uart_rx_byte==8'h5B) ? 9'h041 : // [
|
||||
// (uart_rx_byte==8'h5C) ? 9'h000 : //
|
||||
(uart_rx_byte==8'h5D) ? 9'h040 : // ]
|
||||
// (uart_rx_byte==8'h5E) ? 9'h000 : // ^
|
||||
(uart_rx_byte==8'h5F) ? 9'h04F : // _
|
||||
|
||||
(uart_rx_byte==8'h60) ? 9'h000 : // `
|
||||
(uart_rx_byte==8'h61) ? 9'h001 : // a
|
||||
(uart_rx_byte==8'h62) ? 9'h059 : // b
|
||||
(uart_rx_byte==8'h63) ? 9'h005 : // c
|
||||
(uart_rx_byte==8'h64) ? 9'h007 : // d
|
||||
(uart_rx_byte==8'h65) ? 9'h060 : // e
|
||||
(uart_rx_byte==8'h66) ? 9'h00A : // f
|
||||
(uart_rx_byte==8'h67) ? 9'h05A : // g
|
||||
(uart_rx_byte==8'h68) ? 9'h008 : // h
|
||||
(uart_rx_byte==8'h69) ? 9'h05D : // i
|
||||
(uart_rx_byte==8'h6A) ? 9'h056 : // j
|
||||
(uart_rx_byte==8'h6B) ? 9'h00B : // k
|
||||
(uart_rx_byte==8'h6C) ? 9'h009 : // l
|
||||
(uart_rx_byte==8'h6D) ? 9'h004 : // m
|
||||
(uart_rx_byte==8'h6E) ? 9'h002 : // n
|
||||
(uart_rx_byte==8'h6F) ? 9'h05F : // o
|
||||
|
||||
(uart_rx_byte==8'h70) ? 9'h05C : // p
|
||||
(uart_rx_byte==8'h71) ? 9'h052 : // q
|
||||
(uart_rx_byte==8'h72) ? 9'h003 : // r
|
||||
(uart_rx_byte==8'h73) ? 9'h006 : // s
|
||||
(uart_rx_byte==8'h74) ? 9'h05E : // t
|
||||
(uart_rx_byte==8'h75) ? 9'h05B : // u
|
||||
(uart_rx_byte==8'h76) ? 9'h053 : // v
|
||||
(uart_rx_byte==8'h77) ? 9'h055 : // w
|
||||
(uart_rx_byte==8'h78) ? 9'h051 : // x
|
||||
(uart_rx_byte==8'h79) ? 9'h058 : // y
|
||||
(uart_rx_byte==8'h7A) ? 9'h054 : // z
|
||||
//(uart_rx_byte==8'h7B) ? 9'h000 : // {
|
||||
//(uart_rx_byte==8'h7C) ? 9'h000 : // |
|
||||
//(uart_rx_byte==8'h7D) ? 9'h000 : // }
|
||||
//(uart_rx_byte==8'h7E) ? 9'h000 : // ~
|
||||
//(uart_rx_byte==8'h7F) ? 9'h000 : // DEL
|
||||
|
||||
9'h000;
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// UART RX Controller
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
always @(posedge clk_int)
|
||||
begin
|
||||
|
||||
uart_rx_d <= UART_RX & UART_RX2; // Either of the two serial ports can send data
|
||||
uart_rx_d1 <= uart_rx_d;
|
||||
uart_rx_d2 <= uart_rx_d1;
|
||||
|
||||
rx_count <= rx_count + 1'b1;
|
||||
|
||||
case (rx_count)
|
||||
16'h0000: if (uart_rx_d2!=1'b0) // Look for Start Bit
|
||||
begin
|
||||
rx_count <= 'h0;
|
||||
end
|
||||
16'h0100: uart_rx_byte[7:0] <= 8'h00;
|
||||
16'h019E: uart_rx_byte[0] <= uart_rx_d2;
|
||||
16'h027F: uart_rx_byte[1] <= uart_rx_d2;
|
||||
16'h0367: uart_rx_byte[2] <= uart_rx_d2;
|
||||
16'h0443: uart_rx_byte[3] <= uart_rx_d2;
|
||||
16'h0532: uart_rx_byte[4] <= uart_rx_d2;
|
||||
16'h0611: uart_rx_byte[5] <= uart_rx_d2;
|
||||
16'h06F9: uart_rx_byte[6] <= uart_rx_d2;
|
||||
16'h07DC: uart_rx_byte[7] <= uart_rx_d2;
|
||||
16'h07DD: rx_fifo_wr <= 1'b1;
|
||||
16'h07DE: rx_fifo_wr <= 1'b0;
|
||||
16'h08D0: rx_count <= 'h0;
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// UART TX Controller
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
always @(posedge clk_int)
|
||||
begin
|
||||
|
||||
uart_prescaler <= uart_prescaler + 1'b1;
|
||||
if (uart_prescaler[7:0]==8'h72) // 9600 baud
|
||||
begin
|
||||
uart_clock <= ~ uart_clock;
|
||||
uart_prescaler <= 'h0;
|
||||
end
|
||||
|
||||
uart_clock_d <= uart_clock;
|
||||
|
||||
|
||||
rx_fifo_almost_full_d <= rx_fifo_almost_full;
|
||||
|
||||
if (rx_fifo_almost_full_d==1'b0 && rx_fifo_almost_full==1'b1)
|
||||
begin
|
||||
uart_tx_shiftout <= 11'b1_00010011_01; // XOFF
|
||||
end
|
||||
else if (rx_fifo_almost_full_d==1'b1 && rx_fifo_almost_full==1'b0)
|
||||
begin
|
||||
uart_tx_shiftout <= 11'b1_00010001_01; // XON
|
||||
end
|
||||
else
|
||||
begin
|
||||
if (uart_clock_d==1'b0 && uart_clock==1'b1)
|
||||
begin
|
||||
uart_tx_shiftout[10:0] <= {1'b1 , uart_tx_shiftout[10:1] };
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Main Controller
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
always @(posedge clk_int)
|
||||
begin
|
||||
|
||||
main_count <= main_count + 1'b1;
|
||||
|
||||
case (main_count)
|
||||
8'h00: if (rx_fifo_empty==1'b1) // Poll the rx_fifo for a new character to send
|
||||
begin
|
||||
main_count <= 'h0;
|
||||
end
|
||||
8'h01: rx_fifo_rd <= 1'b1; // Strobe the rx_fifo to get the next character
|
||||
8'h02: rx_fifo_rd <= 1'b0;
|
||||
|
||||
8'h03: if (rx_fifo_data_out[7:0]=='h99) // Check character for carriage return
|
||||
begin
|
||||
main_count <= 8'h10;
|
||||
end
|
||||
|
||||
8'h04: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h121; end // Fill the TX_FIFO with the commands to send a character
|
||||
8'h05: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h00B; end
|
||||
8'h06: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h0A6; end // Delay
|
||||
8'h07: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h121; end
|
||||
8'h08: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h003; end
|
||||
8'h09: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= rx_fifo_data_out; end // Letter to send
|
||||
8'h0A: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h00A; end
|
||||
8'h0B: tx_fifo_wr <= 1'b0;
|
||||
8'h0C: begin
|
||||
if (tx_bytes==16'h8000)
|
||||
begin
|
||||
tx_bytes <= 16'h000A;
|
||||
end
|
||||
else
|
||||
begin
|
||||
tx_bytes <= tx_bytes + 4'hA; // Keep track of how many characters have been printed so far for this row
|
||||
end
|
||||
end
|
||||
8'h0D: if (tx_fifo_empty==1'b0) // Dont add to the TX_FIFO until previous command sequence has completed
|
||||
begin
|
||||
main_count <= main_count;
|
||||
end
|
||||
8'h0E: main_count <= 'h0;
|
||||
|
||||
|
||||
8'h10: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h121; end // Fill the TX_FIFO with the carriage return commands
|
||||
8'h11: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h00B; end
|
||||
8'h12: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h0A6; end // Delay
|
||||
8'h13: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h121; end
|
||||
8'h14: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h00D; end
|
||||
8'h15: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h007; end
|
||||
8'h16: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h121; end
|
||||
8'h17: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h006; end
|
||||
8'h18: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= { 1'b0 , tx_bytes[15:8] }; end
|
||||
8'h19: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= { 1'b0 , tx_bytes[07:0] }; end
|
||||
8'h1A: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h0A6; end // Delay
|
||||
8'h1B: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h121; end
|
||||
8'h1C: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h005; end
|
||||
8'h1D: begin tx_fifo_wr <= 1'b1; tx_fifo_data_in <= 9'h090; end
|
||||
8'h1E: tx_fifo_wr <= 1'b0;
|
||||
8'h1F: tx_bytes <= 16'h8000; // Zero out the character count for this row
|
||||
8'h20: if (tx_fifo_empty==1'b0) // Dont add to the TX_FIFO until previous command sequence has completed
|
||||
begin
|
||||
main_count <= main_count;
|
||||
end
|
||||
8'h21: main_count <= 'h0;
|
||||
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// IBM Bus Controller
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
always @(posedge clk_int)
|
||||
begin
|
||||
|
||||
ibm_bus_d <= IBM_BUS;
|
||||
ibm_bus_d1 <= ibm_bus_d;
|
||||
ibm_bus_d2 <= ibm_bus_d1;
|
||||
|
||||
prescaler <= prescaler + 1'b1;
|
||||
|
||||
if (prescaler[7:0]==8'h05) // IBM Serial Bus clock period = 5.34uS
|
||||
begin
|
||||
ibm_clock <= ~ ibm_clock;
|
||||
prescaler <= 'h0;
|
||||
end
|
||||
|
||||
ibm_clock_d <= ibm_clock;
|
||||
|
||||
// IBM Serial Bus shift register
|
||||
if (ibm_load_tx==1'b1)
|
||||
begin
|
||||
ibm_shift_out[9:0] <= { tx_fifo_data_out[8:0] , 1'b0 };
|
||||
end
|
||||
else if (ibm_clock_d==1'b0 && ibm_clock==1'b1)
|
||||
begin
|
||||
ibm_shift_out[9:0] <= { 1'b1 , ibm_shift_out[9:1] };
|
||||
end
|
||||
|
||||
|
||||
|
||||
ibm_count <= ibm_count + 1'b1;
|
||||
|
||||
case (ibm_count)
|
||||
16'h0000: if (tx_fifo_empty==1'b1) // Poll the tx_fifo
|
||||
begin
|
||||
ibm_count <= 'h0;
|
||||
end
|
||||
16'h0001: tx_fifo_rd <= 1'b1; // Strobe the tx_fifo to get the next character to print
|
||||
16'h0002: tx_fifo_rd <= 1'b0;
|
||||
|
||||
16'h0003: if (tx_fifo_data_out[7:0]==8'hA6) // Check character for the DELAY command byte
|
||||
begin
|
||||
ibm_count <= 16'h0600;
|
||||
end
|
||||
|
||||
16'h0004: if (ibm_clock_d==1'b0 && ibm_clock==1'b1)
|
||||
begin
|
||||
ibm_load_tx <= 1'b1;
|
||||
end
|
||||
else
|
||||
begin
|
||||
ibm_count <= ibm_count;
|
||||
end
|
||||
|
||||
16'h0005: ibm_load_tx <= 1'b0;
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Wait n clocks for end of the sequence to shift out
|
||||
//
|
||||
|
||||
16'h007A: if (ibm_bus_d2!=1'b1) // Check for ACK from IBM
|
||||
begin
|
||||
ibm_count <= ibm_count;
|
||||
end
|
||||
16'h007C: if (ibm_bus_d2!=1'b0) // Check for ACK from IBM
|
||||
begin
|
||||
ibm_count <= ibm_count;
|
||||
end
|
||||
16'h007E: if (ibm_bus_d2!=1'b1) // Check for ACK from IBM
|
||||
begin
|
||||
ibm_count <= ibm_count;
|
||||
end
|
||||
16'h00EC: ibm_count <= 'h0;
|
||||
|
||||
|
||||
16'h0600: ; // Start of Delay
|
||||
16'h1050: ibm_count <= 'h0; // End of Delay
|
||||
|
||||
|
||||
default: ;
|
||||
endcase
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// IBM Bus Snooper
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
always @(posedge clk_int)
|
||||
begin
|
||||
|
||||
snoop_count <= snoop_count + 1'b1;
|
||||
|
||||
case (snoop_count)
|
||||
16'h0000: if (ibm_bus_d2!=1'b0)
|
||||
begin
|
||||
snoop_count <= 'h0;
|
||||
end
|
||||
16'h0012: snoop_byte[0] <= ibm_bus_d2;
|
||||
16'h001E: snoop_byte[1] <= ibm_bus_d2;
|
||||
16'h002A: snoop_byte[2] <= ibm_bus_d2;
|
||||
16'h0036: snoop_byte[3] <= ibm_bus_d2;
|
||||
|
||||
16'h0041: snoop_byte[4] <= ibm_bus_d2;
|
||||
16'h004D: snoop_byte[5] <= ibm_bus_d2;
|
||||
16'h0059: snoop_byte[6] <= ibm_bus_d2;
|
||||
16'h0065: snoop_byte[7] <= ibm_bus_d2;
|
||||
|
||||
16'h0071: snoop_byte[8] <= ibm_bus_d2;
|
||||
16'h0072: snoop_byte_all <= snoop_byte;
|
||||
|
||||
16'h0075: if (ibm_bus_d2!=1'b1)
|
||||
begin
|
||||
snoop_count <= snoop_count;
|
||||
end
|
||||
16'h0077: if (ibm_bus_d2!=1'b0)
|
||||
begin
|
||||
snoop_count <= snoop_count;
|
||||
end
|
||||
16'h0079: if (ibm_bus_d2!=1'b1)
|
||||
begin
|
||||
snoop_count <= snoop_count;
|
||||
end
|
||||
16'h009D: snoop_count <= 'h0;
|
||||
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
|
@ -32,6 +32,28 @@
|
|||
//
|
||||
//------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------
|
||||
//
|
||||
// Copyright (c) 2020 Ted Fried
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
//
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
byte array_in_pointer=0;
|
||||
|
@ -162,4 +184,4 @@ void loop()
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue