Uploaded 10_20_2019

This commit is contained in:
MicroCoreLabs 2019-10-20 12:44:42 -07:00
parent a3352baec2
commit 6ddf6e7d5a
5 changed files with 792 additions and 55 deletions

118
MCL51/Core/MCL51_top.v Normal file
View File

@ -0,0 +1,118 @@
//
//
// File Name : MCL51_top.v
// Used on :
// Author : MicroCore Labs
// Creation : 5/9/2016
// Code Type : Synthesizable
//
// Description:
// ============
//
// MCL51 processor - Top Level For 'Arty' Artix-7 Test Board
//
//------------------------------------------------------------------------
//
// Modification History:
// =====================
//
// Revision 1.0 5/1/16
// Initial revision
//
//
//------------------------------------------------------------------------
module MCL51_top
(
input CLK,
input RESET_n,
input UART_RX,
output UART_TX,
output SPEAKER
);
//------------------------------------------------------------------------
// Internal Signals
wire clk_int;
wire t_rst_n_int;
wire t_biu_reset_out;
wire t_biu_interrupt;
wire [7:0] t_eu_biu_strobe;
wire [7:0] t_eu_biu_dataout;
wire [15:0] t_eu_register_r3;
wire [7:0] t_biu_sfr_psw;
wire [7:0] t_biu_sfr_acc;
wire [7:0] t_biu_sfr_sp;
wire [15:0] t_eu_register_ip;
wire [15:0] t_biu_sfr_dptr;
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
(
.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
(
.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)
);
endmodule // MCL51_top.v
//------------------------------------------------------------------------

View File

@ -0,0 +1,106 @@
//
// File Name : biu_rom_dp_behav.v
// Used on :
// Author : MicroCore Labs
// Creation : 3/17/2016
// Code Type : Behavioral
//
// Description:
// ============
// DPRAM behavioral model.
//
//
//------------------------------------------------------------------------
`timescale 1ns/100ps
module biu_rom_dp
(
input clka,
input wea,
input[11:0] addra,
input[7:0] dina,
output reg[7:0] douta,
input clkb,
input web,
input[11:0] addrb,
input[7:0] dinb,
output reg[7:0] doutb
);
//------------------------------------------------------------------------
integer file, k, l;
reg [7:0] ram_dataouta;
reg [7:0] ram_dataoutb;
reg [7:0] ram_array[0:4095];
//------------------------------------------------------------------------
initial
begin
// Zero out the RAM so there are no X's
for (k = 0; k < 4096 ; k = k + 1)
begin
ram_array[k] = 8'h00;
end
// Load the 8051 instruction into the array
// Using Binary file
file = $fopen("C:/MCL/MCL51/Production_Base/Xilinx_Artix/Loader/Assembly_Code/Loader_Only/Objects/Loader.bin","rb");
for (l = 0; l < 4096 ; l = l + 1)
begin
k = $fread(ram_array[l] , file);
end
end
always @(posedge clka)
begin
douta <= ram_array[addra];
if (wea==1'b1)
begin
ram_array[addra] = dina;
end
else if (web==1'b1)
begin
ram_array[addrb] = dinb;
end
end
always @(posedge clkb)
begin
doutb <= ram_array[addrb];
end
//------------------------------------------------------------------------
endmodule
//------------------------------------------------------------------------

View File

@ -17,24 +17,24 @@
#
# [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[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
# 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
#
#
#
@ -44,37 +44,34 @@
# // 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_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
#
# 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
# 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
# hightea247
# boat98247
# feb 1 1971
# 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
@ -83,18 +80,18 @@
# ----------------
# 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[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[19:16] : Jump Condition:
# 0x0=Unconditional
# 0x1=Last_ALU_Result!=0
# 0x2=Last_ALU_Result==0
# Bits[12:0] : Immediate[12:0]
#
#
@ -105,10 +102,10 @@
# 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
# 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
@ -3029,7 +3026,7 @@ p 01 00000 00000 0252
# r2 =
# r1 = Bit Mask
# r0 = Byte Data
#
#
# -----------------------------------------------------
#
# PC = PC + 1 - Increment to the next opcode byte

168
MCL51/Core/timer.v Normal file
View File

@ -0,0 +1,168 @@
//
//
// File Name : timer.v
// Used on :
// Author : MicroCore Labs
// Creation : 4/15/16
// Code Type : Synthesizable
//
// Description:
// ============
//
// Two channel, 24-bit timers.
//
// Timer-0 = Frequency generator
// Timer-1 = One-shot generator
//
//------------------------------------------------------------------------
//
// Modification History:
// =====================
//
// Revision 1.0 4/15/16
// Initial revision
//
//
//------------------------------------------------------------------------
module timer
(
input CORE_CLK,
input RST_n,
input [3:0] ADDRESS,
input [7:0] DATA_IN,
output [7:0] DATA_OUT,
input STROBE_WR,
output TIMER0_OUT,
output TIMER1_OUT
);
//------------------------------------------------------------------------
// Internal Signals
reg timer0_enable;
reg timer1_enable;
reg timer1_debounce;
reg timer0_out_int;
reg timer1_out_int;
reg [23:0] timer0_counter;
reg [23:0] timer1_counter;
reg [23:0] timer0_count_max;
reg [23:0] timer1_count_max;
//------------------------------------------------------------------------
//
// Combinationals
//
//------------------------------------------------------------------------
assign TIMER0_OUT = (timer0_enable==1'b1 && timer0_out_int==1'b1) ? 1'b1 : 1'b0;
assign TIMER1_OUT = (timer1_enable==1'b1 && timer1_out_int==1'b1) ? 1'b1 : 1'b0;
assign DATA_OUT = 8'h5A; // Timer Device ID
//------------------------------------------------------------------------
//
// Timer
//
//------------------------------------------------------------------------
//
always @(posedge CORE_CLK)
begin : BIU_CONTROLLER
if (RST_n==1'b0)
begin
timer0_count_max <= 24'h02EA85; // C4 - Middle C 261.63Hz @ 100Mhz core frequency
timer0_enable <= 1'b1;
timer0_counter <= 'h0;
timer0_out_int <= 1'b0;
timer1_count_max <= 'h0;
timer1_enable <= 'h0;
timer1_counter <= 'h0;
timer1_out_int <= 1'b0;
timer1_debounce <= 'h0;
end
else
begin
// Writes to Registers
if (STROBE_WR==1'b1)
begin
case (ADDRESS[3:0]) // synthesis parallel_case
4'h0 : timer0_count_max[23:16] <= DATA_IN[7:0];
4'h1 : timer0_count_max[15:8] <= DATA_IN[7:0];
4'h2 : timer0_count_max[7:0] <= DATA_IN[7:0];
4'h3 : timer0_enable <= DATA_IN[0];
4'h4 : timer1_count_max[23:16] <= DATA_IN[7:0];
4'h5 : timer1_count_max[15:8] <= DATA_IN[7:0];
4'h6 : timer1_count_max[7:0] <= DATA_IN[7:0];
4'h7 : timer1_enable <= DATA_IN[0];
4'h8 : timer1_debounce <= 1'b1;
default : ;
endcase
end
else
begin
timer1_debounce <= 1'b0;
end
// Timer0 - Frequency Generator
if (timer0_enable==1'b0 || timer0_counter==timer0_count_max)
begin
timer0_counter <= 'h0;
timer0_out_int <= ~ timer0_out_int;
end
else
begin
timer0_counter <= timer0_counter + 1'b1;
end
// Timer1 - One-shot Generator
if (timer1_enable==1'b0 || timer1_counter==timer1_count_max)
begin
timer1_counter <= 'h0;
end
else
begin
timer1_counter <= timer1_counter + 1'b1;
end
if (timer1_enable==1'b0 || timer1_debounce==1'b1)
begin
timer1_out_int <= 1'b0;
end
else if (timer1_counter==timer1_count_max)
begin
timer1_out_int <= 1'b1;
end
end
end
endmodule // timer.v

View File

@ -0,0 +1,348 @@
//
//
// File Name : uart_and_loader.v
// Used on :
// Author : MicroCore Labs
// Creation : 5/3/16
// Code Type : Synthesizable
//
// Description:
// ============
//
// Fixed 9600 baud rate UART
// Also a Program ROM loader that decodes Intel-Hex format
//
//
// RS232 control characters:
//
// '{' = Put the CPU into RESET and enable the loader
// '}' = Take the CPU out of RESET
//
//
//------------------------------------------------------------------------
module uart_and_loader
(
input CLK,
input RST_n,
input [1:0] ADDRESS,
input [7:0] DATA_IN,
output [7:0] DATA_OUT,
input STROBE_RD,
input STROBE_WR,
input UART_RX,
output UART_TX,
output UART_INT,
output reg [15:0] LOADER_ADDR,
output reg [7:0] LOADER_DATA,
output reg LOADER_WR,
output RESET_OUT
);
//------------------------------------------------------------------------
// Internal Signals
reg RX_STATE = 'h0;
reg uart_rx_d = 1'b1;
reg uart_rx_d1 = 1'b1;
reg uart_rx_d2 = 1'b1;
reg bit_clk = 'h0;
reg bit_clk_d = 'h0;
reg rx_havebyte = 'h0;
reg host_tx_go = 'h0;
reg host_tx_go_d = 'h0;
reg rx_byte_available = 'h0;
reg reset_out_int = 'h0;
reg [7:0] tx_byte = 8'hFF;
reg [10:0] tx_count = 'h0;
reg [10:0] tx_shift_out = 11'b111_1111_1111;
reg [8:0] rx_byte = 9'b1111_1111_1;
reg [13:0] rx_count = 'h0;
reg [4:0] rx_bits = 'h0;
reg [13:0] prescaler = 'h0;
reg [3:0] loader_state = 'h0;
reg [7:0] loader_bytes = 'h0;
reg [15:0] loader_adder_int = 'h0;
wire [1:0] uart_status;
wire [3:0] hex_nibble ;
//------------------------------------------------------------------------
//
// Combinationals
//
//------------------------------------------------------------------------
assign UART_TX = tx_shift_out[0];
assign UART_INT = rx_byte_available;
assign DATA_OUT = (ADDRESS==2'h0) ? rx_byte[7:0] :
(ADDRESS==2'h1) ? uart_status :
8'hEE;
assign uart_status[1] = (tx_count[9:0]==10'b0000000000) ? 1'b0 : 1'b1; // 1=TX_BUSY
assign uart_status[0] = rx_byte_available;
assign hex_nibble = (rx_byte[6]==1'b0) ? rx_byte[3:0] : rx_byte[3:0] + 4'h9;
assign RESET_OUT = reset_out_int;
//------------------------------------------------------------------------
//
// UART Controller
//
//------------------------------------------------------------------------
always @(posedge CLK)
begin : STATE_MACHINE
begin
//------------------------------------------------------------------------
//
// Host interface and prescaler
//
//------------------------------------------------------------------------
// Prescaler fixed for 9600 baud - Xilinx 100Mhz = 14'h28B0
if (prescaler[13:0]==14'h28B0)
begin
bit_clk <= ~ bit_clk;
prescaler <= 'h0;
end
else
begin
prescaler <= prescaler + 1'b1;
end
bit_clk_d <= bit_clk;
// Address: 0x0 - RO - RX_BYTE - reading clears the RX_HAS_BYTE bit
// 0x1 - RO - UART status [1]=TX_BUSY [0]=RX_HAS_BYTE
// 0x2 - WO - TX Byte - Sends the TX byte over UART
// Writes to Registers
if (STROBE_WR==1'b1 && ADDRESS[1:0]==2'h2)
begin
host_tx_go <= 1'b1;
tx_byte <= DATA_IN;
end
else
begin
host_tx_go <= 1'b0;
end
if (rx_havebyte==1'b1)
begin
rx_byte_available <= 1'b1;
end
else if (STROBE_RD==1'b1 && ADDRESS[1:0]==2'h0)
begin
rx_byte_available <= 1'b0;
end
//------------------------------------------------------------------------
//
// RX Controller
//
//------------------------------------------------------------------------
uart_rx_d <= UART_RX;
uart_rx_d1 <= uart_rx_d;
uart_rx_d2 <= uart_rx_d1;
case (RX_STATE) // synthesis parallel_case
1'h0 : begin
// Debounce signals
rx_havebyte <= 1'b0;
rx_bits <= 'h0;
// Look for start bit
if (uart_rx_d2==1'b0)
begin
rx_count <= rx_count + 1'b1;
end
// Count half-way into the start bit
if (rx_count==14'h1458)
begin
rx_count <= 'h0;
rx_byte <= 9'b1_11111111;
RX_STATE <= 1'h1;
end
end
1'h1 : begin
rx_count <= rx_count + 1'b1;
// Count complete bit-times
if (rx_count==14'h28B0)
begin
rx_byte[8:0] <= { uart_rx_d2 , rx_byte[8:1] };
rx_bits <= rx_bits + 1'b1;
rx_count <= 'h0;
end
// Complete byte has been shifted in
if (rx_bits==4'h9)
begin
rx_havebyte <= 1'b1;
RX_STATE <= 1'h0;
end
end
default : ;
endcase
//------------------------------------------------------------------------
//
// TX Controller
//
//------------------------------------------------------------------------
// Load transmit shifter on rising edge of host request
host_tx_go_d <= host_tx_go;
if (host_tx_go_d==1'b0 && host_tx_go==1'b1)
begin
tx_shift_out <= { 1'b1 , tx_byte , 1'b0 , 1'b1 };
tx_count <= 11'b11111111111;
end
// Otherwise shift out bits at each bit clock.
// When tx_count is all zeros tye byte has been sent.
else
begin
if (bit_clk_d != bit_clk)
begin
tx_shift_out[10:0] <= { 1'b1 , tx_shift_out[10:1] };
tx_count[10:0] <= { 1'b0 , tx_count[10:1] };
end
end
//------------------------------------------------------------------------
//
// Program ROM Loader
//
// Snoops the RX line at 9600 baud and decodes Intel-Hex format
//
//------------------------------------------------------------------------
// Perform the steps as each byte is received
//
if (rx_havebyte==1'b1)
begin
// '{' asserts RESET_OUT
if (rx_byte[7:0] == 8'h7B)
begin
reset_out_int <= 1'b1;
end
// '}' deasserts RESET_OUT
if (rx_byte[7:0] == 8'h7D)
begin
reset_out_int <= 1'b0;
end
loader_state <= loader_state + 1'b1;
case (loader_state) // synthesis parallel_case
// Stay in state-0 until the ':' character is received and RESET_OUT is asserted
//
4'h0: begin
if (reset_out_int==1'b1 && rx_byte[7:0] == 8'h3A)
begin
loader_state <= 4'h1;
end
else
begin
loader_state <= 4'h0;
end
end
// Decode the number of bytes in the Intel-Hex string
//
4'h1: begin loader_bytes[7:4] <= hex_nibble; end
4'h2: begin loader_bytes[3:0] <= hex_nibble; end
// Decode the start Address for the following bytes
//
4'h3: begin loader_adder_int[15:12] <= hex_nibble; end
4'h4: begin loader_adder_int[11:8] <= hex_nibble; end
4'h5: begin loader_adder_int[7:4] <= hex_nibble; end
4'h6: begin loader_adder_int[3:0] <= hex_nibble; end
// Ignore the Record Type for now
//
4'h7: ;
4'h8: ;
// Load bytes and increment the loader address until loader_bytes reaches zero
//
4'h9: begin
LOADER_WR <= 1'b0;
LOADER_ADDR <= loader_adder_int;
LOADER_DATA[7:4] <= hex_nibble;
if (loader_bytes == 8'h00)
begin
loader_state <= 4'h0;
end
end
4'hA: begin
LOADER_WR <= 1'b1;
LOADER_DATA[3:0] <= hex_nibble;
loader_adder_int <= loader_adder_int + 1'b1;
loader_bytes <= loader_bytes - 1'b1;
loader_state <= 4'h9;
end
default : ;
endcase
end
end
end
endmodule