// ============================================================================ // >>>>>>>>>>>>>>>>>>>>>>>>>>>>> COPYRIGHT NOTICE <<<<<<<<<<<<<<<<<<<<<<<<<<<<< // ---------------------------------------------------------------------------- // Copyright (c) 2006-2011 by Lattice Semiconductor Corporation // ALL RIGHTS RESERVED // ---------------------------------------------------------------------------- // // IMPORTANT: THIS FILE IS AUTO-GENERATED BY THE LATTICEMICO SYSTEM. // // Permission: // // Lattice Semiconductor grants permission to use this code // pursuant to the terms of the Lattice Semiconductor Corporation // Open Source License Agreement. // // Disclaimer: // // Lattice Semiconductor provides no warranty regarding the use or // functionality of this code. It is the user's responsibility to // verify the user’s design for consistency and functionality through // the use of formal verification methods. // // ---------------------------------------------------------------------------- // // Lattice Semiconductor Corporation // 5555 NE Moore Court // Hillsboro, OR 97214 // U.S.A // // TEL: 1-800-Lattice (USA and Canada) // 503-286-8001 (other locations) // // web: http://www.latticesemi.com/ // email: techsupport@latticesemi.com // // ---------------------------------------------------------------------------- // FILE DETAILS // // Name : lm8_idec.v // Project : LatticeMico8 // Dependencies : n/a // Description : LatticeMico8 microcontroller core's instruction decode logic. // Revisions : 3.2 (Initial version) // : 3.3 (n/a) // ============================================================================ module lm8_idec #( parameter PROM_AW=10 ) ( input [17:0] instr, output reg imi_instr, output reg sub, output reg subc, output reg add, output reg addc, output reg mov, output reg andr, output reg orr, output reg xorr, output reg cmp, output reg test, output reg ror1, output reg rorc, output reg rol1, output reg rolc, output reg clrc, output reg setc, output reg clrz, output reg setz, output reg clri, output reg seti, output reg bz, output reg bnz, output reg bc, output reg bnc, output reg b, output reg callz, output reg callnz, output reg callc, output reg callnc, output reg call, output reg ret, output reg iret, output reg export, output reg import, output reg exporti, output reg importi, output reg ssp, output reg lsp, output reg sspi, output reg lspi, output reg wcsr, output reg rcsr, output reg [4:0] addr_rb, output reg [4:0] addr_rd, output reg [7:0] imi_data, output reg [PROM_AW -1:0] addr_jmp, output reg update_c, output reg update_z ); reg instr_l1_0, instr_l1_1, instr_l1_2, instr_l1_3; reg instr_l2_0, instr_l2_1, instr_l2_2, instr_l2_3; reg instr_l3_0, instr_l3_1; reg instr_l4_0, instr_l4_1; reg instr_l5_0, instr_l5_1, instr_l5_2, instr_l5_3; reg instr_l6_0, instr_l6_1; reg instr_l7_0, instr_l7_1, instr_l7_2, instr_l7_3; reg ro; reg sc; reg br0; reg ca0, ca1; reg re; reg iels; reg iels_ie; reg iels_ls; always @(/*AUTOSENSE*/instr) begin // Level 1 decodes of bits [17:16] instr_l1_0 = (~instr[17] & ~instr[16]); instr_l1_1 = (~instr[17] & instr[16]); instr_l1_2 = (instr[17] & ~instr[16]); instr_l1_3 = (instr[17] & instr[16]); // Level 2 decodes of bits [15:14] instr_l2_0 = (~instr[15] & ~instr[14]); instr_l2_1 = (~instr[15] & instr[14]); instr_l2_2 = (instr[15] & ~instr[14]); instr_l2_3 = (instr[15] & instr[14]); // Level 3 decodes of bits [13] instr_l3_0 = ~instr[13]; instr_l3_1 = instr[13]; // Level 4 decodes of bits [12] instr_l4_0 = ~instr[12]; instr_l4_1 = instr[12]; // Level 5 decodes of bits [11:10] instr_l5_0 = (~instr[11] & ~instr[10]); instr_l5_1 = (~instr[11] & instr[10]); instr_l5_2 = (instr[11] & ~instr[10]); instr_l5_3 = (instr[11] & instr[10]); // Level 6 decodes of bits [2] instr_l6_0 = ~instr[2]; instr_l6_1 = instr[2]; // Level 7 decodes of bits [1:0] instr_l7_0 = (~instr[1] & ~instr[0]); instr_l7_1 = (~instr[1] & instr[0]); instr_l7_2 = (instr[1] & ~instr[0]); instr_l7_3 = (instr[1] & instr[0]); end always @(/*AUTOSENSE*/instr or instr_l1_0 or instr_l1_1 or instr_l1_2 or instr_l1_3 or instr_l2_0 or instr_l2_1 or instr_l2_2 or instr_l2_3 or instr_l3_0 or instr_l3_1 or instr_l4_0 or instr_l4_1 or instr_l6_0 or instr_l6_1 or instr_l7_0 or instr_l7_1 or instr_l7_2 or instr_l7_3) begin // Immidiate operand instruction de imi_instr = instr_l3_1; // Decodes for sub* instructions sub = instr_l1_0 & instr_l2_0; subc = instr_l1_0 & instr_l2_1; // Decodes for add* instructions add = instr_l1_0 & instr_l2_2; addc = instr_l1_0 & instr_l2_3; // Decodes for mov* instructions mov = instr_l1_1 & instr_l2_0; // Decodes for logic* instructions andr = instr_l1_1 & instr_l2_1; orr = instr_l1_1 & instr_l2_2; xorr = instr_l1_1 & instr_l2_3; // Decodes for compare/test instructions cmp = instr_l1_2 & instr_l2_0; test = instr_l1_2 & instr_l2_1; // Decodes for rotate instructions ro = instr_l1_2 & instr_l2_2 & instr_l3_0; ror1 = ro & instr_l7_0; rorc = ro & instr_l7_2; rol1 = ro & instr_l7_1; rolc = ro & instr_l7_3; // Decodes for set/clear instructions sc = instr_l1_2 & instr_l2_3 & instr_l3_0; clrc = sc & instr_l6_0 & instr_l7_0; setc = sc & instr_l6_0 & instr_l7_1; clrz = sc & instr_l6_0 & instr_l7_2; setz = sc & instr_l6_0 & instr_l7_3; clri = sc & instr_l6_1 & instr_l7_0; seti = sc & instr_l6_1 & instr_l7_1; // Decodes for import/export instructions iels = instr_l1_2 & instr_l2_3 & instr_l3_1; iels_ie = iels & instr_l6_0; export = iels_ie & instr_l7_0; import = iels_ie & instr_l7_1; exporti = iels_ie & instr_l7_2; importi = iels_ie & instr_l7_3; // Decodes for load/store instructions iels_ls = iels & instr_l6_1; ssp = iels_ls & instr_l7_0; lsp = iels_ls & instr_l7_1; sspi = iels_ls & instr_l7_2; lspi = iels_ls & instr_l7_3; // Decodes for branch instructions br0 = instr_l1_3 & instr_l2_0; bz = br0 & instr_l3_0 & instr_l4_0; bnz = br0 & instr_l3_0 & instr_l4_1; bc = br0 & instr_l3_1 & instr_l4_0; bnc = br0 & instr_l3_1 & instr_l4_1; // Decodes for call instructions ca0 = instr_l1_3 & instr_l2_1; callz = ca0 & instr_l3_0 & instr_l4_0; callnz = ca0 & instr_l3_0 & instr_l4_1; callc = ca0 & instr_l3_1 & instr_l4_0; callnc = ca0 & instr_l3_1 & instr_l4_1; // Decodes for unconditional branch/call/return instructions re = instr_l1_3 & instr_l2_2; ca1 = instr_l1_3 & instr_l2_2; call = ca1 & instr_l3_0 & instr_l4_0; ret = re & instr_l3_0 & instr_l4_1; iret = re & instr_l3_1 & instr_l4_0; b = ca1 & instr_l3_1 & instr_l4_1; // Decodes for control & status instructions rcsr = instr_l1_2 & instr_l2_3 & instr_l3_0 & instr_l6_1 & instr_l7_2; wcsr = instr_l1_2 & instr_l2_3 & instr_l3_0 & instr_l6_1 & instr_l7_3; // Undefined Opcode // undef_op = instr_l1_3 & instr_l2_3; // Rd address addr_rd = instr[12:8]; // Rb address addr_rb = instr[7:3]; // Constant data from immidiate instructions imi_data = instr[7:0]; // Enable Carry/Zero Flag update update_c = (instr_l1_0 | ( instr_l1_2 & ~instr_l2_3 & instr[1]) | (instr_l1_2 & instr_l2_0)); update_z = (instr_l1_0 | // add/sub (instr_l1_1 & ~instr_l2_0) | // and/or/xor ro | // rotate cmp | // compare test); // test // setz and clrz do not activate update_z, but are used directly // by the async_z logic in lm8_flow_ctrl. end // Label from branch/call instructions generate if (PROM_AW <= 12) always @(instr) addr_jmp = instr[PROM_AW-1:0]; else always @(instr) addr_jmp = {{PROM_AW-12{instr[11]}},instr[11:0]}; endgenerate endmodule