📄 mdu.v
字号:
parameter[7:0] CPL_C = 8'b10110011;
parameter[7:0] CJNE_A_N = 8'b10110100;
parameter[7:0] CJNE_A_ADDR = 8'b10110101;
parameter[7:0] CJNE_IR0_N = 8'b10110110;
parameter[7:0] CJNE_IR1_N = 8'b10110111;
parameter[7:0] CJNE_R0_N = 8'b10111000;
parameter[7:0] CJNE_R1_N = 8'b10111001;
parameter[7:0] CJNE_R2_N = 8'b10111010;
parameter[7:0] CJNE_R3_N = 8'b10111011;
parameter[7:0] CJNE_R4_N = 8'b10111100;
parameter[7:0] CJNE_R5_N = 8'b10111101;
parameter[7:0] CJNE_R6_N = 8'b10111110;
parameter[7:0] CJNE_R7_N = 8'b10111111;
// C0H - CFh
parameter[7:0] PUSH = 8'b11000000;
parameter[7:0] AJMP_6 = 8'b11000001;
parameter[7:0] CLR_BIT = 8'b11000010;
parameter[7:0] CLR_C = 8'b11000011;
parameter[7:0] SWAP_A = 8'b11000100;
parameter[7:0] XCH_ADDR = 8'b11000101;
parameter[7:0] XCH_IR0 = 8'b11000110;
parameter[7:0] XCH_IR1 = 8'b11000111;
parameter[7:0] XCH_R0 = 8'b11001000;
parameter[7:0] XCH_R1 = 8'b11001001;
parameter[7:0] XCH_R2 = 8'b11001010;
parameter[7:0] XCH_R3 = 8'b11001011;
parameter[7:0] XCH_R4 = 8'b11001100;
parameter[7:0] XCH_R5 = 8'b11001101;
parameter[7:0] XCH_R6 = 8'b11001110;
parameter[7:0] XCH_R7 = 8'b11001111;
// D0H - DFh
parameter[7:0] POP = 8'b11010000;
parameter[7:0] ACALL_6 = 8'b11010001;
parameter[7:0] SETB_BIT = 8'b11010010;
parameter[7:0] SETB_C = 8'b11010011;
parameter[7:0] DA_A = 8'b11010100;
parameter[7:0] DJNZ_ADDR = 8'b11010101;
parameter[7:0] XCHD_IR0 = 8'b11010110;
parameter[7:0] XCHD_IR1 = 8'b11010111;
parameter[7:0] DJNZ_R0 = 8'b11011000;
parameter[7:0] DJNZ_R1 = 8'b11011001;
parameter[7:0] DJNZ_R2 = 8'b11011010;
parameter[7:0] DJNZ_R3 = 8'b11011011;
parameter[7:0] DJNZ_R4 = 8'b11011100;
parameter[7:0] DJNZ_R5 = 8'b11011101;
parameter[7:0] DJNZ_R6 = 8'b11011110;
parameter[7:0] DJNZ_R7 = 8'b11011111;
// E0H - EFh
parameter[7:0] MOVX_A_IDPTR = 8'b11100000;
parameter[7:0] AJMP_7 = 8'b11100001;
parameter[7:0] MOVX_A_IR0 = 8'b11100010;
parameter[7:0] MOVX_A_IR1 = 8'b11100011;
parameter[7:0] CLR_A = 8'b11100100;
parameter[7:0] MOV_A_ADDR = 8'b11100101;
parameter[7:0] MOV_A_IR0 = 8'b11100110;
parameter[7:0] MOV_A_IR1 = 8'b11100111;
parameter[7:0] MOV_A_R0 = 8'b11101000;
parameter[7:0] MOV_A_R1 = 8'b11101001;
parameter[7:0] MOV_A_R2 = 8'b11101010;
parameter[7:0] MOV_A_R3 = 8'b11101011;
parameter[7:0] MOV_A_R4 = 8'b11101100;
parameter[7:0] MOV_A_R5 = 8'b11101101;
parameter[7:0] MOV_A_R6 = 8'b11101110;
parameter[7:0] MOV_A_R7 = 8'b11101111;
// F0H - FFh
parameter[7:0] MOVX_IDPTR_A = 8'b11110000;
parameter[7:0] ACALL_7 = 8'b11110001;
parameter[7:0] MOVX_IR0_A = 8'b11110010;
parameter[7:0] MOVX_IR1_A = 8'b11110011;
parameter[7:0] CPL_A = 8'b11110100;
parameter[7:0] MOV_ADDR_A = 8'b11110101;
parameter[7:0] MOV_IR0_A = 8'b11110110;
parameter[7:0] MOV_IR1_A = 8'b11110111;
parameter[7:0] MOV_R0_A = 8'b11111000;
parameter[7:0] MOV_R1_A = 8'b11111001;
parameter[7:0] MOV_R2_A = 8'b11111010;
parameter[7:0] MOV_R3_A = 8'b11111011;
parameter[7:0] MOV_R4_A = 8'b11111100;
parameter[7:0] MOV_R5_A = 8'b11111101;
parameter[7:0] MOV_R6_A = 8'b11111110;
parameter[7:0] MOV_R7_A = 8'b11111111;
//-----------------------------------------------------------------
// Interrupt reset values
//-----------------------------------------------------------------
parameter[4:0] VECT_RV = 5'b00000; // Interrupt Vector reset value
parameter[3:0] IS_REG_RV = 4'b0000; // In Service Register reset value
//-----------------------------------------------------------------
// Interrupt Vector locations
//-----------------------------------------------------------------
// external interrupt 0
parameter[4:0] VECT_E0 = 5'b00000;
// timer 0 overflow
parameter[4:0] VECT_TF0 = 5'b00001;
// external interrupt 1
parameter[4:0] VECT_E1 = 5'b00010;
// timer 1 overflow
parameter[4:0] VECT_TF1 = 5'b00011;
// serial channel 0
parameter[4:0] VECT_SER0 = 5'b00100;
// timer 2 overflow/ext. reload
parameter[4:0] VECT_TF2 = 5'b00101;
// A/D converter
parameter[4:0] VECT_ADC = 5'b01000;
// external interrupt 2
parameter[4:0] VECT_EX2 = 5'b01001;
// external interrupt 3
parameter[4:0] VECT_EX3 = 5'b01010;
// external interrupt 4
parameter[4:0] VECT_EX4 = 5'b01011;
// external interrupt 5
parameter[4:0] VECT_EX5 = 5'b01100;
// external interrupt 6
parameter[4:0] VECT_EX6 = 5'b01101;
// serial channel 1
parameter[4:0] VECT_SER1 = 5'b10000;
//-----------------------------------------------------------------
// Start address location
//-----------------------------------------------------------------
parameter[15:0] ADDR_RV = 16'b0000000000000000; //
//-----------------------------------------------------------------
// RAM & SFR address reset value
//-----------------------------------------------------------------
parameter[7:0] RAM_SFR_ADDR_RV= 8'b00000000; //
//-----------------------------------------------------------------
// Data register reset value
//-----------------------------------------------------------------
parameter[7:0] DATAREG_RV = 8'b00000000; //
//-----------------------------------------------------------------
// High ordered half of address during indirect addressing
//-----------------------------------------------------------------
parameter[7:0] ADDR_HIGH_RI = 8'b00000000; //
//-----------------------------------------------------------------
// Watchdog Timer reset value
//-----------------------------------------------------------------
parameter[6:0] WDTH_RV = 7'b0000000; // High ordered WDT
parameter[7:0] WDTL_RV = 8'b00000000; // Low ordered WDT
//-----------------------------------------------------------------
// Watchdog Timer reset state
//-----------------------------------------------------------------
parameter[14:0] WDT_RS = 15'b111111111111100; // X"7FFC"
//*******************************************************************--
// Control signals inputs
input clk; // Global clock input
input rst; // Global reset input
// Special function register interface
input [7:0] sfrdatai;
output [7:0] sfrdatamdu;
wire [7:0] sfrdatamdu;
input [6:0] sfraddr;
input sfrwe;
input sfroe;
//---------------------------------------------------------------
// FSM states enumeration type
//---------------------------------------------------------------
parameter [3:0] ST14 = 0;
parameter [3:0] ST13 = 1;
parameter [3:0] ST12 = 2;
parameter [3:0] ST11 = 3;
parameter [3:0] ST10 = 4;
parameter [3:0] ST9 = 5;
parameter [3:0] ST8 = 6;
parameter [3:0] ST7 = 7;
parameter [3:0] ST6 = 8;
parameter [3:0] ST5 = 9;
parameter [3:0] ST4 = 10;
parameter [3:0] ST3 = 11;
parameter [3:0] ST2 = 12;
parameter [3:0] ST1 = 13;
parameter [3:0] ST0 = 14;
//---------------------------------------------------------------
// Operation select enumeration type
//---------------------------------------------------------------
parameter [3:0] MUL = 0;
parameter [3:0] DIV32 = 1;
parameter [3:0] LDRES = 2;
parameter [3:0] DIV16 = 3;
parameter [3:0] SHR = 4;
parameter [3:0] SHL = 5;
parameter [3:0] NORM = 6;
parameter [3:0] NOP_ = 7;
parameter [3:0] MD32RST = 8;
//---------------------------------------------------------------
// MDU operation select enumeration type
//---------------------------------------------------------------
parameter [2:0] MDU_RST = 0;
parameter [2:0] MDU_MUL = 1;
parameter [2:0] MDU_DIV16 = 2;
parameter [2:0] MDU_DIV32 = 3;
parameter [2:0] MDU_SHIFT = 4;
parameter [2:0] MDU_NOP = 5;
//---------------------------------------------------------------
// Special Function Registers
//---------------------------------------------------------------
// Arithmetic Control Register
reg [7:0] arcon;
// Multiplication/Division Registers
reg [7:0] md0;
reg [7:0] md1;
reg [7:0] md2;
reg [7:0] md3;
reg [7:0] md4;
reg [7:0] md5;
//---------------------------------------------------------------
// Utility registers
//---------------------------------------------------------------
reg [15:0] norm_reg;
reg [4:0] counter_st;
reg [4:0] counter_nxt;
// Combinational adder
reg [17:0] sum;
reg [17:0] sum1;
// FSM registers and signals
reg [3:0] lmdx_reg; // load mdx register sequence detect
reg [3:0] lmdx_nxt;
reg [3:0] oper_reg; // arithmetic operation FSM
reg [3:0] oper_nxt;
// Control signals
reg [3:0] md30_sel; // md3 ... md0 mux addr
reg [1:0] counter_sel;//count select
reg ld_sc; // load sc (in arcon register)
reg [2:0] mdu_op; // mdu operation
reg opend; // mdu operation end
reg setmdef; // set mdef flag
reg setmdov; // set mdov flag
//------------------------------------------------------------------
// SFR arcon register write
//------------------------------------------------------------------
always @(posedge clk)
begin : arcon_write_proc
//------------------------------------------------------------------
if (rst)
//-----------------------------------
// Synchronous reset
//-----------------------------------
begin
arcon <= ARCON_RV ;
end
else
begin
//-----------------------------------
// Synchronous write
//-----------------------------------
// Special function register write
//--------------------------------
if (sfrwe & sfraddr == ARCON_ID) // arcon(7 downto 6) is read only
begin
arcon[5:0] <= sfrdatai[5:0] ;
end
else
begin
//--------------------------------
// load sc
//--------------------------------
if (ld_sc)
begin
arcon[4:0] <= ~(counter_st - 1'b1) ;
end
else if (oper_reg == ST5 | oper_reg == ST6)
begin
arcon[4:0] <= counter_nxt ;
end
end
if (sfroe & (sfraddr == ARCON_ID))
begin
arcon[7] <= 1'b0 ;
end
else
begin
//--------------------------------
// mdef flag
//--------------------------------
if (setmdef)
begin
arcon[7] <= 1'b1 ;
end
end
if (sfrwe & sfraddr == MD0_ID)
begin
arcon[6] <= 1'b0 ;
end
else
begin
//--------------------------------
// mdov flag
//--------------------------------
if (setmdov)
begin
arcon[6] <= 1'b1 ;
end
end
end
end
//------------------------------------------------------------------
// SFR md0 register write
//------------------------------------------------------------------
always @(posedge clk)
begin : md0_write_proc
//------------------------------------------------------------------
if (rst)
//-----------------------------------
// Synchronous reset
//-----------------------------------
begin
md0 <= MD0_RV ;
end
else
//-----------------------------------
// Synchronous write
//-----------------------------------
// Special function register write
//--------------------------------
begin
if (sfrwe & sfraddr == MD0_ID)
begin
md0 <= sfrdatai ;
end
else
begin
case (md30_sel)
SHL :
begin
if (counter_st[4] | counter_st[3] |
counter_st[2] | counter_st[1])
begin
md0 <= {md0[5:0], 2'b00} ;
end
else
begin
md0 <= {md0[6:0], 1'b0} ;
end
end
SHR :
begin
if (counter_st[4] | counter_st[3] |
counter_st[2] | counter_st[1])
begin
md0 <= {md1[1:0], md0[7:2]} ;
end
else
begin
md0 <= {md1[0], md0[7:1]} ;
end
end
NORM :
begin
if (md3[6])
begin
md0 <= {md0[6:0], 1'b0} ;
end
else
begin
md0 <= {md0[5:0], 2'b00} ;
end
end
DIV32, DIV16, LDRES :
begin
md0 <= {md0[5:0], sum1[17], sum[17]} ;
end
MUL :
begin
md0 <= {md1[1:0], md0[7:2]} ;
end
endcase
end
end
end
//------------------------------------------------------------------
// SFR md1 register write
//------------------------------------------------------------------
always @(posedge clk)
begin : md1_write_proc
//------------------------------------------------------------------
if (rst)
//-----------------------------------
// Synchronous reset
//-----------------------------------
begin
md1 <= MD1_RV ;
end
else
//-----------------------------------
// Synchronous write
//-----------------------------------
// Special function register write
//--------------------------------
begin
if (sfrwe & sfraddr == MD1_ID)
begin
md1 <= sfrdatai ;
end
else
begin
case (md30_sel)
SHL :
begin
if (counter_st[4] | counter_st[3] |
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -