405 lines
11 KiB
Coq
405 lines
11 KiB
Coq
|
//
|
||
|
//
|
||
|
// File Name : biu.v
|
||
|
// Used on :
|
||
|
// Author : 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
|
||
|
//
|
||
|
//
|
||
|
//------------------------------------------------------------------------
|
||
|
|
||
|
|
||
|
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
|
||
|
|
||
|
|