426 lines
14 KiB
Verilog
426 lines
14 KiB
Verilog
//
|
|
//
|
|
// File Name : biu.v
|
|
// Used on :
|
|
// Author : Ted Fried, MicroCore Labs
|
|
// Creation : 3/13/16
|
|
// Code Type : Synthesizable
|
|
//
|
|
// Description:
|
|
// ============
|
|
//
|
|
// Bus Interface Unit of the MCL51 processor
|
|
// ported to the Lattice XO2 Breakout Board.
|
|
//
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// Modification History:
|
|
// =====================
|
|
//
|
|
// Revision 1.0 3/13/16
|
|
// 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.
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
module biu
|
|
(
|
|
input CORE_CLK, // Core Signals
|
|
input RST_n,
|
|
|
|
|
|
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,
|
|
|
|
output RESET_OUT
|
|
|
|
);
|
|
|
|
//------------------------------------------------------------------------
|
|
|
|
|
|
// Internal Signals
|
|
|
|
reg biu_pxy_rd;
|
|
reg biu_pxy_wr;
|
|
reg core_interrupt_disable;
|
|
wire biu_int2;
|
|
wire biu_int3;
|
|
wire biu_sfr_select;
|
|
wire acc_parity;
|
|
wire biu_timer_wr_strobe;
|
|
wire biu_uart_rd_strobe;
|
|
wire biu_uart_wr_strobe;
|
|
wire loader_wr;
|
|
reg [15:0] eu_register_r3_d1;
|
|
reg [7:0] biu_sfr_dpl_int;
|
|
reg [7:0] biu_sfr_dph_int;
|
|
reg [7:0] biu_sfr_ie_int;
|
|
reg [7:0] biu_sfr_psw_int;
|
|
reg [7:0] biu_sfr_acc_int;
|
|
reg [7:0] biu_sfr_sp_int;
|
|
reg [7:0] biu_sfr_b_int;
|
|
reg [7:0] biu_sfr_pxy_addr;
|
|
reg [7:0] biu_sfr_pxy_dout;
|
|
wire [7:0] biu_sfr_pxy_din;
|
|
wire [7:0] biu_sfr_dataout;
|
|
wire [7:0] biu_sfr_is_int;
|
|
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 [15:0] loader_addr_int;
|
|
wire [7:0] loader_data_int;
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// User Program ROM. 4Kx8
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
/* Program ROM without interface to the UART Loader
|
|
biu_rom BIU_4Kx8
|
|
(
|
|
.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
|
|
(
|
|
.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 ( )
|
|
);
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// User Data RAM. 512x8
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
// For Lattice XO2 Series FPGAs
|
|
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)
|
|
);
|
|
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// BIU Combinationals
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
|
|
// Outputs to the EU
|
|
//
|
|
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_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
|
|
// This can be removed if parity is not used in firmware.
|
|
assign acc_parity = (biu_sfr_acc_int[0]^biu_sfr_acc_int[1]^biu_sfr_acc_int[2]^biu_sfr_acc_int[3]^biu_sfr_acc_int[4]^biu_sfr_acc_int[5]^biu_sfr_acc_int[6]^biu_sfr_acc_int[7]);
|
|
|
|
|
|
|
|
|
|
|
|
// 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];
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
|
|
// Decode the write enable to the RAM block
|
|
assign biu_ram_wr = (biu_sfr_select==1'b0 && eu_biu_strobe_int==3'h1) ? 1'b1 : 1'b0;
|
|
|
|
|
|
// 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 :
|
|
(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'hE0) ? biu_sfr_acc_int :
|
|
(eu_register_r3_d1[7:0]==8'hF0) ? biu_sfr_b_int :
|
|
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
|
|
//
|
|
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 ;
|
|
|
|
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 ;
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// BIU Controller
|
|
//
|
|
//------------------------------------------------------------------------
|
|
//
|
|
|
|
always @(posedge CORE_CLK)
|
|
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;
|
|
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
|
|
end
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
//------------------------------------------------------------------------
|
|
//------------------------------------------------------------------------
|
|
|
|
//
|
|
// Peripherals accessed with proxy addressing
|
|
//
|
|
// BIU SFR biu_sfr_pxy_addr - 0xC2 = Address[7:0]
|
|
// biu_sfr_pxy_dout - 0xC1 = Write Data and strobe to the peripherals
|
|
// biu_sfr_pxy_din - 0xC0 = Read Data from the peripherals
|
|
//
|
|
//
|
|
//
|
|
//------------------------------------------------------------------------
|
|
//
|
|
|
|
// 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 ;
|
|
|
|
// 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;
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// Timer - Dual output 24-bit programmable timer
|
|
//
|
|
// Timer-0 = Frequency generator
|
|
// Timer-1 = Pulse generator
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
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)
|
|
);
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------
|
|
//
|
|
// UART - Fixed 9600 baud
|
|
//
|
|
//------------------------------------------------------------------------
|
|
|
|
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),
|
|
|
|
.LOADER_ADDR (loader_addr_int ),
|
|
.LOADER_DATA (loader_data_int ),
|
|
.LOADER_WR (loader_wr ),
|
|
.RESET_OUT (RESET_OUT )
|
|
|
|
);
|
|
|
|
|
|
endmodule // biu.v
|
|
|
|
|