Uploaded 10_20_2019
This commit is contained in:
parent
a3352baec2
commit
6ddf6e7d5a
|
@ -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
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
|
@ -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
|
||||
|
||||
|
||||
//------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
||||
|
|
@ -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
|
Loading…
Reference in New Issue