risc_core.v
Upload User: lifezer
Upload Date: 2013-03-20
Package Size: 25k
Code Size: 24k
Development Platform:

MultiPlatform

  1. /////////////////////////////////////////////////////////////////////
  2. ////                                                             ////
  3. ////  Mini-RISC-1                                                ////
  4. ////  Mini-Risc Core                                             ////
  5. ////                                                             ////
  6. ////                                                             ////
  7. ////  Author: Rudolf Usselmann                                   ////
  8. ////          rudi@asics.ws                                      ////
  9. ////                                                             ////
  10. ////                                                             ////
  11. ////  D/L from: http://www.opencores.org/cores/minirisc/         ////
  12. ////                                                             ////
  13. /////////////////////////////////////////////////////////////////////
  14. ////                                                             ////
  15. //// Copyright (C) 2000-2002 Rudolf Usselmann                    ////
  16. ////                         www.asics.ws                        ////
  17. ////                         rudi@asics.ws                       ////
  18. ////                                                             ////
  19. //// This source file may be used and distributed without        ////
  20. //// restriction provided that this copyright statement is not   ////
  21. //// removed from the file and that any derivative work contains ////
  22. //// the original copyright notice and the associated disclaimer.////
  23. ////                                                             ////
  24. ////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ////
  25. //// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ////
  26. //// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ////
  27. //// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ////
  28. //// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ////
  29. //// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ////
  30. //// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ////
  31. //// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ////
  32. //// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ////
  33. //// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ////
  34. //// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ////
  35. //// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ////
  36. //// POSSIBILITY OF SUCH DAMAGE.                                 ////
  37. ////                                                             ////
  38. /////////////////////////////////////////////////////////////////////
  39. //  CVS Log
  40. //
  41. //  $Id: risc_core.v,v 1.3 2002/10/01 12:44:24 rudi Exp $
  42. //
  43. //  $Date: 2002/10/01 12:44:24 $
  44. //  $Revision: 1.3 $
  45. //  $Author: rudi $
  46. //  $Locker:  $
  47. //  $State: Exp $
  48. //
  49. // Change History:
  50. //               $Log: risc_core.v,v $
  51. //               Revision 1.3  2002/10/01 12:44:24  rudi
  52. //               Tweaked code a bit - trying to get it run faster ...
  53. //
  54. //               Revision 1.2  2002/09/27 15:35:40  rudi
  55. //               Minor update to newer devices ...
  56. //
  57. //
  58. //
  59. //
  60. //
  61. //
  62. //
  63. //
  64. //
  65. //
  66. //
  67. `timescale 1ns / 10ps
  68. module mrisc(
  69.    clk,
  70.    rst_in,
  71.    
  72.    inst_addr,
  73.    inst_data,
  74.    portain,
  75.    portbin,
  76.    portcin,
  77.    portaout,
  78.    portbout,
  79.    portcout,
  80.    trisa,
  81.    trisb,
  82.    trisc,
  83.    
  84.    tcki,
  85.    wdt_en );
  86. // Basic Core I/O.
  87. input clk;
  88. input rst_in;
  89. // Program memory interface
  90. output [10:0] inst_addr;
  91. input  [11:0] inst_data;
  92. // Basic I/O Ports
  93. input  [7:0] portain;
  94. input  [7:0] portbin;
  95. input  [7:0] portcin;
  96. output [7:0] portaout;
  97. output [7:0] portbout;
  98. output [7:0] portcout;
  99. output [7:0] trisa;
  100. output [7:0] trisb;
  101. output [7:0] trisc;
  102. input tcki;
  103. input wdt_en;
  104. // This should be set to the ROM location where our restart vector is.
  105. // As set here, we have 512 words of program space.
  106. parameter PC_RST_VECTOR = 11'h000, // Should be: 11'h7FF,
  107. STAT_RST_VALUE = 8'h18,
  108. OPT_RST_VALUE = 8'h3f,
  109. FSR_RST_VALUE = 7'h0,
  110. TRIS_RST_VALUE = 8'hff;
  111. parameter ALU_ADD = 4'h0,
  112. ALU_SUB  = 4'h1,
  113. ALU_INC  = 4'h2,
  114. ALU_DEC  = 4'h3,
  115. ALU_AND  = 4'h4,
  116. ALU_CLR  = 4'h5,
  117. ALU_NOT  = 4'h6,
  118. ALU_IOR  = 4'h7,
  119. ALU_MOV  = 4'h8,
  120. ALU_MOVW = 4'h9,
  121. ALU_RLF  = 4'ha,
  122. ALU_RRF  = 4'hb,
  123. ALU_SWP  = 4'hc,
  124. ALU_XOR  = 4'hd,
  125. ALU_BCF  = 4'he,
  126. ALU_BSF  = 4'hf;
  127. parameter // Byte Oriented RF Operations
  128. I_ADDWF = 12'b0001_11??_????,
  129. I_ANDWF = 12'b0001_01??_????,
  130. I_CLRF = 12'b0000_011?_????,
  131. I_CLRW = 12'b0000_0100_0000,
  132. I_COMF = 12'b0010_01??_????,
  133. I_DEC = 12'b0000_11??_????,
  134. I_DECFSZ = 12'b0010_11??_????,
  135. I_INCF = 12'b0010_10??_????,
  136. I_INCFSZ = 12'b0011_11??_????,
  137. I_IORWF = 12'b0001_00??_????,
  138. I_MOV = 12'b0010_00??_????,
  139. I_MOVWF = 12'b0000_001?_????,
  140. I_NOP = 12'b0000_0000_0000,
  141. I_RLF = 12'b0011_01??_????,
  142. I_RRF = 12'b0011_00??_????,
  143. I_SUBWF = 12'b0000_10??_????,
  144. I_SWAPF = 12'b0011_10??_????,
  145. I_XORWF = 12'b0001_10??_????,
  146. // Bit Oriented RF Operations
  147. I_BCF = 12'b0100_????_????,
  148. I_BSF = 12'b0101_????_????,
  149. I_BTFSC = 12'b0110_????_????,
  150. I_BTFSS = 12'b0111_????_????,
  151. // Literal & Controll Operations
  152. I_ANDLW = 12'b1110_????_????,
  153. I_CALL = 12'b1001_????_????,
  154. I_CLRWDT = 12'b0000_0000_0100,
  155. I_GOTO = 12'b101?_????_????,
  156. I_IORLW = 12'b1101_????_????,
  157. I_MOVLW = 12'b1100_????_????,
  158. I_OPTION = 12'b0000_0000_0010,
  159. I_RETLW = 12'b1000_????_????,
  160. I_SLEEP = 12'b0000_0000_0011,
  161. I_TRIS = 12'b0000_0000_0???,
  162. I_XORLW = 12'b1111_????_????;
  163. parameter // sfr register address encodings
  164. INDF_ADDR = 3'h0,
  165. TMR0_ADDR = 3'h1,
  166. PCL_ADDR = 3'h2,
  167. STAT_ADDR = 3'h3,
  168. FSR_ADDR = 3'h4,
  169. PORTA_ADDR = 3'h5,
  170. PORTB_ADDR = 3'h6,
  171. PORTC_ADDR = 3'h7;
  172. parameter // Source 1 Select
  173. K_SEL = 2'b10,
  174. SFR_SEL  = 2'b00,
  175. RF_SEL = 2'b01;
  176. parameter // STATUS Register status bits we
  177. STAT_WR_C = 3'b001,
  178. STAT_WR_DC = 3'b010,
  179. STAT_WR_Z = 3'b100;
  180. // Instruction Register
  181. reg rst;
  182. reg  [11:0] instr_0, instr_1;
  183. reg rst_r1, rst_r2;
  184. wire valid;
  185. reg valid_1;
  186. reg  [7:0] mask;
  187. reg  [7:0] sfr_rd_data;
  188. reg  [3:0] alu_op;
  189. reg   src1_sel;
  190. reg  [1:0] src1_sel_;
  191. wire [7:0] dout; // ALU output
  192. wire [7:0] src1; // ALU Source 1
  193. reg  [2:0] stat_bwe; // status bits we
  194. wire c_out, dc_out, z_out;
  195. reg pc_skz, pc_skz_;
  196. reg pc_bset, pc_bset_;
  197. reg pc_bclr, pc_bclr_;
  198. reg pc_call, pc_call_;
  199. reg pc_goto, pc_goto_;
  200. reg pc_retlw, pc_retlw_;
  201. wire invalidate_1;
  202. wire invalidate_0_;
  203. reg invalidate_0;
  204. // stage 1 dst decode
  205. reg w_we_;
  206. reg rf_we_;
  207. reg sfr_we_;
  208. reg tris_we_;
  209. // stage 2 dst decode
  210. reg w_we;
  211. wire rf_we;
  212. reg rf_we1, rf_we2, rf_we3;
  213. reg opt_we;
  214. reg trisa_we;
  215. reg trisb_we;
  216. reg trisc_we;
  217. wire indf_we_;
  218. reg tmr0_we;
  219. wire pc_we_;
  220. reg pc_we;
  221. reg stat_we;
  222. reg fsr_we;
  223. reg porta_we;
  224. reg portb_we;
  225. reg portc_we;
  226. wire bit_sel;
  227. wire [7:0] tmr0_next, tmr0_next1, tmr0_plus_1;
  228. wire tmr0_cnt_en;
  229. reg wdt_clr;
  230. wire wdt_to;
  231. wire wdt_en;
  232. wire tcki;
  233. wire [7:0] sfr_rd_data_tmp1, sfr_rd_data_tmp2, sfr_rd_data_tmp3;
  234. // Register File Connections
  235. wire [1:0] rf_rd_bnk, rf_wr_bnk;
  236. wire [4:0] rf_rd_addr, rf_wr_addr;
  237. wire [7:0] rf_rd_data, rf_wr_data;
  238. // Program Counter 
  239. reg  [10:0] inst_addr;
  240. reg  [10:0] pc;
  241. wire [10:0] pc_next;
  242. wire [10:0] pc_plus_1;
  243. wire [10:0] stack_out;
  244. reg  [10:0] pc_r, pc_r2;
  245. wire [10:0] pc_next1, pc_next2, pc_next3;
  246. // W Register
  247. reg  [7:0] w; // Working Register
  248. reg  [7:0] status; // Status Register
  249. wire [7:0] status_next;
  250. reg  [6:0] fsr; // fsr register ( for indirect addressing)
  251. wire [6:0] fsr_next;
  252. reg  [7:0] tmr0; // Timer 0
  253. reg  [5:0] option; // Option Register
  254. // Tristate Control registers. 
  255. reg [7:0] trisa;
  256. reg [7:0] trisb;
  257. reg [7:0] trisc;
  258. // I/O Port registers
  259. reg [7:0] porta_r; // PORTA input register
  260. reg [7:0] portb_r; // PORTB input register
  261. reg [7:0] portc_r; // PORTC input register
  262. reg [7:0] portaout; // PORTA output register
  263. reg [7:0] portbout; // PORTB output register
  264. reg [7:0] portcout; // PORTC output register
  265. ////////////////////////////////////////////////////////////////////////
  266. // External Reset is Synchrounous to clock
  267. always @(posedge clk)
  268. rst <= #1 rst_in;
  269. ////////////////////////////////////////////////////////////////////////
  270. // Synchrounous Register File
  271. register_file u0( .clk( clk ),
  272. .rst( rst ),
  273. .rf_rd_bnk( rf_rd_bnk ),
  274. .rf_rd_addr( rf_rd_addr ),
  275. .rf_rd_data( rf_rd_data ),
  276. .rf_we( rf_we ),
  277. .rf_wr_bnk( rf_wr_bnk ),
  278. .rf_wr_addr( rf_wr_addr ),
  279. .rf_wr_data( rf_wr_data )
  280. );
  281. ////////////////////////////////////////////////////////////////////////
  282. // Always Fetch Next Instruction
  283. always @(posedge clk)
  284. instr_0 <= #1 inst_data;
  285. ////////////////////////////////////////////////////////////////////////
  286. // Instr Decode & Read Logic
  287. always @(posedge clk)
  288.    begin
  289. rst_r1 <= #1 rst | wdt_to;
  290. rst_r2 <= #1 rst | rst_r1 | wdt_to;
  291.    end
  292. assign valid = ~rst_r2 & ~invalidate_1;
  293. always @(posedge clk)
  294. valid_1 <= #1 valid;
  295. always @(posedge clk)
  296.     instr_1 <= #1 instr_0;
  297. always @(posedge clk) // Basic Decode extracted directly from the instruction
  298.    begin
  299. // Mask for bit modification instructions
  300. case(instr_0[7:5]) // synopsys full_case parallel_case 
  301.    0: mask <= #1 8'h01;
  302.    1: mask <= #1 8'h02;
  303.    2: mask <= #1 8'h04;
  304.    3: mask <= #1 8'h08;
  305.    4: mask <= #1 8'h10;
  306.    5: mask <= #1 8'h20;
  307.    6: mask <= #1 8'h40;
  308.    7: mask <= #1 8'h80;
  309. endcase
  310.    end
  311. always @(posedge clk)
  312. pc_r <= #1 pc; // Previous version of PC to accomodate for pipeline
  313. always @(posedge clk) // SFR Read Operands
  314.    if(src1_sel_[1]) sfr_rd_data <= #1 instr_0[7:0];
  315.    else
  316.    case(instr_0[2:0]) // synopsys full_case parallel_case
  317.       1: sfr_rd_data <= #1 tmr0_next;
  318.       2: sfr_rd_data <= #1 pc_r[7:0];
  319.       3: sfr_rd_data <= #1 status_next;
  320.       4: sfr_rd_data <= #1 {1'b1, fsr_next};
  321.       5: sfr_rd_data <= #1 porta_r;
  322.       6: sfr_rd_data <= #1 portb_r;
  323.       7: sfr_rd_data <= #1 portc_r;
  324.    endcase
  325. /*
  326. always @(posedge clk)
  327. sfr_rd_data <= #1 sfr_rd_data_tmp1;
  328. reg [3:0] sfr_sel;
  329. wire [3:0] sfr_sel_src;
  330. assign sfr_sel_src = {src1_sel_[1],instr_0[2:0]};
  331. always @(sfr_sel_src)
  332. casex(sfr_sel_src) // synopsys full_case parallel_case
  333.    4'b1_???: sfr_sel = 4'b01_11;
  334.    4'b0_001: sfr_sel = 4'bxx_00;
  335.    4'b0_010: sfr_sel = 4'b00_11;
  336.    4'b0_011: sfr_sel = 4'bxx_01;
  337.    4'b0_100: sfr_sel = 4'bxx_10;
  338.    4'b0_101: sfr_sel = 4'b10_11;
  339.    4'b0_11?: sfr_sel = 4'b11_11;
  340. endcase
  341. mux4_8 u1( .sel(sfr_sel[1:0]), .out(sfr_rd_data_tmp1),
  342. .in0(tmr0_next), .in1(status_next),
  343. .in2({1'b1, fsr_next}), .in3(sfr_rd_data_tmp2) );
  344. mux4_8 u2( .sel(sfr_sel[3:2]), .out(sfr_rd_data_tmp2),
  345. .in0(pc_r[7:0]), .in1(instr_0[7:0]),
  346. .in2(porta_r), .in3(sfr_rd_data_tmp3) );
  347. mux2_8 u2b( .sel(instr_0[0]), .out(sfr_rd_data_tmp3),
  348. .in0(portb_r), .in1(portc_r) );
  349. */
  350. reg instd_zero;
  351. always @(posedge clk)
  352. instd_zero <= #1 !(|inst_data[4:0]);
  353. // Register File Read Port
  354. assign rf_rd_bnk  = fsr_next[6:5];
  355. assign rf_rd_addr = instd_zero ? fsr_next[4:0] : instr_0[4:0];
  356. // ALU OP
  357. always @(posedge clk)
  358.    casex(instr_0) // synopsys full_case parallel_case
  359. // Byte Oriented RF Operations
  360.       I_ADDWF: alu_op <= #1 ALU_ADD; // ADDWF
  361.       I_ANDWF: alu_op <= #1 ALU_AND; // ANDWF
  362.       I_CLRF: alu_op <= #1 ALU_CLR; // CLRF
  363.       I_CLRW: alu_op <= #1 ALU_CLR; // CLRW
  364.       I_COMF: alu_op <= #1 ALU_NOT; // COMF
  365.       I_DEC: alu_op <= #1 ALU_DEC; // DEC
  366.       I_DECFSZ: alu_op <= #1 ALU_DEC; // DECFSZ
  367.       I_INCF: alu_op <= #1 ALU_INC; // INCF
  368.       I_INCFSZ: alu_op <= #1 ALU_INC; // INCFSZ
  369.       I_IORWF: alu_op <= #1 ALU_IOR; // IORWF
  370.       I_MOV: alu_op <= #1 ALU_MOV; // MOV
  371.       I_MOVWF: alu_op <= #1 ALU_MOVW; // MOVWF
  372.       I_RLF: alu_op <= #1 ALU_RLF; // RLF
  373.       I_RRF: alu_op <= #1 ALU_RRF; // RRF
  374.       I_SUBWF: alu_op <= #1 ALU_SUB; // SUBWF
  375.       I_SWAPF: alu_op <= #1 ALU_SWP; // SWAPF
  376.       I_XORWF: alu_op <= #1 ALU_XOR; // XORWF
  377. // Bit Oriented RF Operations
  378.       I_BCF: alu_op <= #1 ALU_BCF; // BCF
  379.       I_BSF: alu_op <= #1 ALU_BSF; // BSF
  380. // Literal & Controll Operations
  381.       I_ANDLW: alu_op <= #1 ALU_AND; // ANDLW
  382.       I_IORLW: alu_op <= #1 ALU_IOR; // IORLW
  383.       I_MOVLW: alu_op <= #1 ALU_MOV; // MOWLW
  384.       I_RETLW: alu_op <= #1 ALU_MOV; // RETLW
  385.       I_XORLW: alu_op <= #1 ALU_XOR; // XORLW
  386.    endcase
  387. // Source Select
  388. // This CPU source 1 can be one of: rf (or sfr) or k,
  389. // second source (if any) is always w
  390. always @(instr_0)
  391.    casex(instr_0) // synopsys full_case parallel_case
  392.       I_ANDLW: src1_sel_ = K_SEL;
  393.       I_CALL: src1_sel_ = K_SEL;
  394.       I_GOTO: src1_sel_ = K_SEL;
  395.       I_IORLW: src1_sel_ = K_SEL;
  396.       I_MOVLW: src1_sel_ = K_SEL;
  397.       I_RETLW: src1_sel_ = K_SEL;
  398.       I_XORLW: src1_sel_ = K_SEL;
  399.       default: src1_sel_ = ( (instr_0[4:3]==2'h0) & (instr_0[2:0] != 3'h0 )) ? SFR_SEL : RF_SEL;
  400.    endcase
  401. always @(posedge clk)
  402. src1_sel <= #1 src1_sel_[0];
  403. // Destination Select
  404. // Destination can be one of: rf, w, option, tris OR one of sfr registers: 
  405. // indf, tmr0, pc, status, fsr, porta, portb, portc, option, trisa, trisb, trisc
  406. // Stage 1
  407. // select w, pc, rf or sfr
  408. reg w_we1, w_we1_;
  409. always @(instr_0)
  410.    begin
  411. casex(instr_0) // synopsys full_case parallel_case
  412.    I_ADDWF, I_ANDWF, I_COMF, I_DEC,
  413.    I_DECFSZ, I_INCF, I_INCFSZ, I_IORWF,
  414.    I_MOV, I_RLF, I_RRF, I_SUBWF,
  415.    I_SWAPF, I_XORWF: // w or f
  416. w_we1_ = 1;
  417.    default:  w_we1_ = 0;
  418. endcase
  419.    end
  420.    
  421. always @(instr_0)
  422.    begin
  423. w_we_ = 0;
  424. rf_we_ = 0;
  425. sfr_we_ = 0;
  426. tris_we_= 0;
  427. casex(instr_0) // synopsys full_case parallel_case
  428.    I_ADDWF, I_ANDWF, I_COMF, I_DEC,
  429.    I_DECFSZ, I_INCF, I_INCFSZ, I_IORWF,
  430.    I_MOV, I_RLF, I_RRF, I_SUBWF,
  431.    I_SWAPF, I_XORWF: // w or f
  432.    begin
  433. rf_we_ = instr_0[5] & (instr_0[4] | instr_0[3]);
  434. sfr_we_ = instr_0[5] & ~instr_0[4] & ~instr_0[3];
  435.    end
  436.    I_MOVWF, I_CLRF, I_BCF, I_BSF: // only f
  437.    begin
  438. rf_we_ = instr_0[4] | instr_0[3];
  439. sfr_we_ = ~instr_0[4] & ~instr_0[3];
  440.    end
  441.    I_CLRW, I_IORLW, I_MOVLW,
  442.    I_ANDLW, I_RETLW, I_XORLW: w_we_ = 1; // only w
  443.    I_TRIS: tris_we_ = 1; // trisa or trisb or trisc
  444. endcase
  445.    end
  446. assign indf_we_ = sfr_we_ & (instr_0[2:0] == INDF_ADDR);
  447. assign  pc_we_   = sfr_we_ & (instr_0[2:0] == PCL_ADDR);
  448. // Stage 2 destination encoder
  449. // write enable outputs are registered now
  450. always @(posedge clk) w_we <= #1 w_we_; // working register write 0 enable
  451. always @(posedge clk) w_we1 <= #1 w_we1_; // working register write 1 enable
  452. // Register File Write Enable is composed of thee conditions: 1) direct register writing (0x10-0x1f);
  453. // 2) Direct Global Register writing (0x08-0x0f), and 3) Indirect Register File Writing
  454. // The logic has been partitioned and balanced between the decode and execute stage ...
  455. assign rf_we = rf_we1 |  (rf_we2 & rf_we3); // register file write enable Composite
  456. always @(posedge clk)
  457. rf_we1 <= #1 valid & rf_we_; // register file write enable 1
  458. always @(posedge clk)
  459. rf_we2 <= #1 valid & (fsr_next[4] | fsr_next[3]);// register file write enable 2 
  460. always @(posedge clk)
  461. rf_we3 <= #1 indf_we_; // register file write enable 3
  462. always @(posedge clk)
  463. wdt_clr <= #1 instr_0[11:0] == I_CLRWDT;
  464. always @(posedge clk)
  465. opt_we <= #1 instr_0[11:0] == I_OPTION;
  466. always @(posedge clk)
  467. trisa_we <= #1 tris_we_ & (instr_0[2:0] == PORTA_ADDR);
  468. always @(posedge clk)
  469. trisb_we <= #1 tris_we_ & (instr_0[2:0] == PORTB_ADDR);
  470. always @(posedge clk)
  471. trisc_we <= #1 tris_we_ & (instr_0[2:0] == PORTC_ADDR);
  472. always @(posedge clk)
  473.    begin
  474. // SFR registers
  475. tmr0_we <= #1 sfr_we_ & (instr_0[2:0] == TMR0_ADDR);
  476. pc_we <= #1 valid & pc_we_;
  477. stat_we <= #1 valid & sfr_we_ & (instr_0[2:0] == STAT_ADDR);
  478. fsr_we <= #1 valid & sfr_we_ & (instr_0[2:0] == FSR_ADDR);
  479. porta_we <= #1 sfr_we_ & (instr_0[2:0] == PORTA_ADDR);
  480. portb_we <= #1 sfr_we_ & (instr_0[2:0] == PORTB_ADDR);
  481. portc_we <= #1 sfr_we_ & (instr_0[2:0] == PORTC_ADDR);
  482.   end
  483. // Instructions that directly modify PC
  484. always @(instr_0)
  485.    begin
  486. pc_skz_  = 0;
  487. pc_bset_ = 0;
  488. pc_bclr_ = 0;
  489. pc_call_ = 0;
  490. pc_goto_ = 0;
  491. pc_retlw_ = 0;
  492. casex(instr_0) // synopsys full_case parallel_case
  493. // Byte Oriented RF Operations
  494.    I_DECFSZ,
  495.    I_INCFSZ: pc_skz_ = 1;
  496. // Bit Oriented RF Operations
  497.    I_BTFSS: pc_bset_ = 1;
  498.    I_BTFSC: pc_bclr_ = 1;
  499. // Literal & Controll Operations
  500.    I_CALL: pc_call_ = 1;
  501.    I_GOTO: pc_goto_ = 1;
  502.    I_RETLW: pc_retlw_ = 1;
  503. endcase
  504.    end
  505. always @(posedge clk)
  506.    begin
  507. pc_skz   <= #1 valid & pc_skz_;
  508. pc_bset  <= #1 valid & pc_bset_;
  509. pc_bclr  <= #1 valid & pc_bclr_;
  510. pc_call  <= #1 valid & pc_call_;
  511. pc_goto  <= #1 valid & pc_goto_;
  512. pc_retlw <= #1 valid & pc_retlw_;
  513.    end
  514. assign invalidate_0_ = (pc_call_ | pc_goto_ | pc_retlw_ | pc_we_);
  515. always @(posedge clk)
  516.     invalidate_0 <= #1 invalidate_0_;
  517. // Status bits WE
  518. always @(posedge clk)
  519.    begin
  520. stat_bwe <= #1 0;
  521. if(valid)
  522. casex(instr_0) // synopsys full_case parallel_case
  523. // Byte Oriented RF Operations
  524.    I_ADDWF: stat_bwe <= #1 STAT_WR_C | STAT_WR_DC | STAT_WR_Z;
  525.    I_ANDWF: stat_bwe <= #1 STAT_WR_Z;
  526.    I_CLRF: stat_bwe <= #1 STAT_WR_Z;
  527.    I_CLRW: stat_bwe <= #1 STAT_WR_Z;
  528.    I_COMF: stat_bwe <= #1 STAT_WR_Z;
  529.    I_DEC: stat_bwe <= #1 STAT_WR_Z;
  530.    I_INCF: stat_bwe <= #1 STAT_WR_Z;
  531.      I_IORWF: stat_bwe <= #1 STAT_WR_Z;
  532.    I_MOV: stat_bwe <= #1 STAT_WR_Z;
  533.    I_RLF: stat_bwe <= #1 STAT_WR_C;
  534.    I_RRF: stat_bwe <= #1 STAT_WR_C;
  535.    I_SUBWF: stat_bwe <= #1 STAT_WR_C | STAT_WR_DC | STAT_WR_Z;
  536.    I_XORWF: stat_bwe <= #1 STAT_WR_Z;
  537. // Literal & Controll Operations
  538.    I_ANDLW: stat_bwe <= #1 STAT_WR_Z;
  539.    //I_CLRWDT: // Modifies TO & PD   *** FIX ME ***
  540.    I_IORLW: stat_bwe <= #1 STAT_WR_Z;
  541.    //I_SLEEP: // Modifies TO & PD   *** FIX ME ***
  542.    I_XORLW: stat_bwe <= #1 STAT_WR_Z;
  543. endcase
  544.  end
  545. ////////////////////////////////////////////////////////////////////////
  546. // Wr & Execute Logic (including PC)
  547. // Second Pipeline Stage
  548. ////////////////////////////////////////////////////////////////////////
  549. // Source OP Sel
  550. //assign src1 = src1_sel ? rf_rd_data : sfr_rd_data;
  551. mux2_8 u3( .sel(src1_sel), .in0(sfr_rd_data), .in1(rf_rd_data), .out(src1) );
  552. alu u4( .s1( src1 ),
  553. .s2( w ),
  554. .mask( mask ),
  555. .out( dout ),
  556. .op( alu_op ),
  557. .c_in( status[0] ),
  558. .c( c_out ),
  559. .dc( dc_out ),
  560. .z( z_out )
  561. );
  562. // Register file connections
  563. assign rf_wr_bnk  = fsr[6:5];
  564. assign  rf_wr_addr = (instr_1[4:0]==0) ? fsr[4:0] : instr_1[4:0];
  565. assign  rf_wr_data = dout;
  566. wire [7:0] status_next2;
  567. // Deal with all special registers (SFR) writes
  568. /*
  569. always @(rst or status or stat_we or stat_bwe or dout or c_out or dc_out or z_out)
  570. if(rst) status_next = STAT_RST_VALUE;
  571. else
  572.    begin
  573. status_next = status; // Default Keep Value
  574. if(stat_we) status_next = dout | 8'h18;
  575. else
  576.    begin
  577. if(stat_bwe[0]) status_next[0] = c_out;
  578. if(stat_bwe[1]) status_next[1] = dc_out;
  579. if(stat_bwe[2]) status_next[2] = z_out;
  580.    end
  581.    end
  582. */
  583. assign status_next2[0] = stat_bwe[0] ?  c_out : status[0];
  584. assign status_next2[1] = stat_bwe[1] ? dc_out : status[1];
  585. assign status_next2[2] = stat_bwe[2] ?  z_out : status[2];
  586. mux2_8 u21( .sel(stat_we), .in1( {dout | 8'h18} ), .in0( {status[7:3],status_next2[2:0]} ), .out(status_next) );
  587. always @(posedge clk)
  588. if(rst) status <= #1 STAT_RST_VALUE;
  589. else status <= #1 status_next;
  590. //assign fsr_next = fsr_we ? dout[6:0] : fsr;
  591. mux2_7 u31( .sel(fsr_we), .in1(dout[6:0]), .in0(fsr), .out(fsr_next) );
  592. always @(posedge clk)
  593. if(rst) fsr <= #1 FSR_RST_VALUE;
  594. else fsr <= #1 fsr_next;
  595. always @(posedge clk)
  596.     if(valid_1 & (w_we | (w_we1 & ~instr_1[5])) ) w <= #1 dout;
  597. always @(posedge clk)
  598. if(rst) trisa <= #1 TRIS_RST_VALUE;
  599. else
  600. if(trisa_we & valid_1) trisa <= #1 w;
  601. always @(posedge clk)
  602. if(rst) trisb <= #1 TRIS_RST_VALUE;
  603. else
  604. if(trisb_we & valid_1) trisb <= #1 w;
  605. always @(posedge clk)
  606. if(rst) trisc <= #1 TRIS_RST_VALUE;
  607. else
  608. if(trisc_we & valid_1) trisc <= #1 w;
  609. always @(posedge clk)
  610. if(rst) option <= #1 OPT_RST_VALUE;
  611. else
  612. if(opt_we & valid_1) option <= #1 w[5:0];
  613. always @(posedge clk)
  614. if(porta_we & valid_1) portaout <= #1 dout;
  615. always @(posedge clk)
  616. if(portb_we & valid_1) portbout <= #1 dout;
  617. always @(posedge clk)
  618. if(portc_we & valid_1) portcout <= #1 dout;
  619. always @(posedge clk)
  620.    begin
  621. porta_r <= #1 portain;
  622. portb_r <= #1 portbin;
  623. portc_r <= #1 portcin;
  624.    end
  625. ///////////////////////////////////////////////////////////////////////
  626. // Timer Logic
  627. //assign tmr0_next = tmr0_we ? dout : tmr0_cnt_en ? tmr0_plus_1 : tmr0;
  628. //assign tmr0_next = tmr0_we ? dout : tmr0_cnt_en ? (tmr0 + 1) : tmr0;
  629. mux2_8 u5( .sel(tmr0_we & valid_1),
  630. .in0(tmr0_next1), .in1(dout),
  631. .out(tmr0_next) );
  632. mux2_8 u6( .sel(tmr0_cnt_en),
  633. .in0(tmr0), .in1(tmr0_plus_1),
  634. .out(tmr0_next1) );
  635. inc8 u7( .in(tmr0), .out(tmr0_plus_1) );
  636. always @(posedge clk)
  637. tmr0 <= #1 tmr0_next;
  638. presclr_wdt u8( .clk( clk ),
  639. .rst( rst ),
  640. .tcki( tcki ),
  641. .option( option[5:0] ),
  642. .tmr0_we( tmr0_we & valid_1 ), 
  643. .tmr0_cnt_en( tmr0_cnt_en ),
  644. .wdt_en( wdt_en ),
  645. .wdt_clr( wdt_clr & valid_1 ),
  646. .wdt_to( wdt_to )
  647. );
  648. ////////////////////////////////////////////////////////////////////////
  649. // Programm Counter Logic
  650. always @(posedge clk)
  651. pc_r2 <= #1 pc_r;
  652. // 'inst_addr' is a duplication of the 'pc'. The only time when it is really needed
  653. // is when the program memory is not on the chip and we want to place the registers
  654. // directly in the IO pads to reduce Tcq (For example in a Xilinx FPGA implementation).
  655. // If the program memory is on the chip or if the implmentation allows feedback from
  656. // registers in the IO cells, this is not needed. Synopsys FPGA compiler appears to
  657. // make the correct decission either way, and gett rid of unneded logic ...
  658. always @(posedge clk)
  659. if(rst) inst_addr <= #1 PC_RST_VECTOR;
  660. else inst_addr <= #1 pc_next;
  661. always @(posedge clk)
  662. if(rst) pc <= #1 PC_RST_VECTOR;
  663. else pc <= #1 pc_next;
  664. /*
  665. always @(pc_plus_1 or dout or pc_we or status or stack_out or
  666. pc_call or pc_goto or pc_retlw or instr_1)
  667. if(pc_we) pc_next = {status[6:5], 1'b0, dout};
  668. else
  669. if(!pc_call & !pc_goto & !pc_retlw) pc_next = pc_plus_1;
  670. else
  671. if(pc_call) pc_next = {status[6:5], 1'b0, instr_1[7:0]};
  672. else
  673. if(pc_goto) pc_next = {status[6:5], instr_1[8:0]};
  674. else
  675. if(pc_retlw) pc_next = stack_out;
  676. */
  677. wire  [10:0] pc_tmp1, pc_tmp2, pc_tmp3;
  678. wire pc_sel1;
  679. assign pc_tmp1 = {status[6:5], 1'b0, dout[7:0]};
  680. assign pc_tmp2 = {status[6:5], 1'b0, instr_1[7:0]};
  681. assign pc_tmp3 = {status[6:5], instr_1[8:0]};
  682. assign pc_sel1 = (!pc_call & !pc_goto & !pc_retlw);
  683. mux2_11 u9 ( .sel(pc_we),   .in0(pc_next1),  .in1(pc_tmp1),   .out(pc_next)  );
  684. mux2_11 u10( .sel(pc_sel1), .in0(pc_next2),  .in1(pc_plus_1), .out(pc_next1) );
  685. mux2_11 u11( .sel(pc_call), .in0(pc_next3),  .in1(pc_tmp2),   .out(pc_next2) );
  686. mux2_11 u12( .sel(pc_goto), .in0(stack_out), .in1(pc_tmp3),   .out(pc_next3) );
  687. inc11 u13( .in(pc), .out(pc_plus_1) );
  688. reg invalidate_1_r1, invalidate_1_r2;
  689. assign invalidate_1 = (pc_skz & z_out) | (pc_bset & bit_sel) |
  690.   (pc_bclr & !bit_sel) | (invalidate_0 & valid_1) | invalidate_1_r1;
  691. always @(posedge clk)
  692.    begin
  693. invalidate_1_r1 <= #1 (invalidate_0 & valid_1) | invalidate_1_r2;
  694. invalidate_1_r2 <= #1 (invalidate_0 & valid_1);
  695.    end
  696. //assign bit_sel = src1[ instr_1[7:5] ];
  697. mux8_1 u22( .sel(instr_1[7:5]), .in(src1), .out(bit_sel) );
  698. sfifo4x11 u14( .clk(clk), .push(pc_call), .din(pc_r2), .pop(pc_retlw), .dout(stack_out) );
  699. endmodule