upd77c25.v 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679
  1. `timescale 1ns / 1ps
  2. //////////////////////////////////////////////////////////////////////////////////
  3. // Engineer: ikari
  4. //
  5. // Create Date: 17:09:03 01/16/2011
  6. // Design Name:
  7. // Module Name: upd77c25
  8. // Project Name: sd2snes
  9. // Target Devices: xc3s400
  10. // Tool versions: ISE 13.1
  11. // Description: NEC uPD77C25 core (for SNES DSP1-4)
  12. //
  13. // Dependencies:
  14. //
  15. // Revision:
  16. // Revision 0.2 - core fully operational, firmware download
  17. //
  18. //////////////////////////////////////////////////////////////////////////////////
  19. module upd77c25(
  20. input [7:0] DI,
  21. output [7:0] DO,
  22. input A0,
  23. input nCS,
  24. input nRD,
  25. input nWR,
  26. input RST,
  27. input CLK,
  28. input PGM_WR,
  29. input [23:0] PGM_DI,
  30. input [10:0] PGM_WR_ADDR,
  31. input DAT_WR,
  32. input [15:0] DAT_DI,
  33. input [10:0] DAT_WR_ADDR,
  34. input DP_nCS,
  35. input [10:0] DP_ADDR,
  36. // debug
  37. output [15:0] DR,
  38. output [15:0] SR,
  39. output [10:0] PC,
  40. output [15:0] A,
  41. output [15:0] B,
  42. output [5:0] FL_A,
  43. output [5:0] FL_B
  44. );
  45. parameter STATE_FETCH = 8'b00000001;
  46. parameter STATE_LOAD = 8'b00000010;
  47. parameter STATE_ALU1 = 8'b00000100;
  48. parameter STATE_ALU2 = 8'b00001000;
  49. parameter STATE_STORE = 8'b00010000;
  50. parameter STATE_NEXT = 8'b00100000;
  51. parameter STATE_IDLE1 = 8'b01000000;
  52. parameter STATE_IDLE2 = 8'b10000000;
  53. parameter I_OP = 2'b00;
  54. parameter I_RT = 2'b01;
  55. parameter I_JP = 2'b10;
  56. parameter I_LD = 2'b11;
  57. parameter SR_RQM = 15;
  58. parameter SR_DRS = 12;
  59. parameter SR_DRC = 10;
  60. reg [1:0] flags_ov0;
  61. reg [1:0] flags_ov1;
  62. reg [1:0] flags_z;
  63. reg [1:0] flags_c;
  64. reg [1:0] flags_s0;
  65. reg [1:0] flags_s1;
  66. reg [10:0] pc; // program counter
  67. reg [7:0] insn_state; // execute state
  68. reg [1:0] regs_dpb;
  69. reg [3:0] regs_dph;
  70. reg [3:0] regs_dpl;
  71. reg [10:0] regs_rp;
  72. wire [15:0] ram_dina;
  73. reg [15:0] ram_dina_r;
  74. assign ram_dina = ram_dina_r;
  75. wire [10:0] pgm_addra;
  76. wire [23:0] pgm_dina;
  77. wire [23:0] pgm_doutb;
  78. upd77c25_pgmrom pgmrom (
  79. .clka(CLK), // input clka
  80. .wea(PGM_WR), // input [0 : 0] wea
  81. .addra(PGM_WR_ADDR), // input [10 : 0] addra
  82. .dina(PGM_DI), // input [23 : 0] dina
  83. .clkb(CLK), // input clkb
  84. .addrb(pc), // input [10 : 0] addrb
  85. .doutb(pgm_doutb) // output [23 : 0] doutb
  86. );
  87. wire [23:0] opcode_w = pgm_doutb;
  88. reg [23:0] opcode;
  89. reg [1:0] op;
  90. reg [1:0] op_pselect;
  91. reg [3:0] op_alu;
  92. reg op_asl;
  93. reg [1:0] op_dpl;
  94. reg [3:0] op_dphm;
  95. reg op_rpdcr;
  96. reg [3:0] op_src;
  97. reg [3:0] op_dst;
  98. wire [9:0] dat_addra;
  99. wire [15:0] dat_dina;
  100. wire [15:0] dat_doutb;
  101. upd77c25_datrom datrom (
  102. .clka(CLK), // input clka
  103. .wea(DAT_WR), // input [0 : 0] wea
  104. .addra(DAT_WR_ADDR), // input [9 : 0] addra
  105. .dina(DAT_DI), // input [15 : 0] dina
  106. .clkb(CLK), // input clkb
  107. .addrb(regs_rp), // input [10 : 0] addrb
  108. .doutb(dat_doutb) // output [15 : 0] doutb
  109. );
  110. reg [7:0] reg_nCS_sreg;
  111. initial reg_nCS_sreg = 8'b11111111;
  112. always @(posedge CLK) reg_nCS_sreg <= {reg_nCS_sreg[6:0], nCS};
  113. reg [5:0] reg_oe_sreg;
  114. initial reg_oe_sreg = 6'b111111;
  115. always @(posedge CLK) reg_oe_sreg <= {reg_oe_sreg[4:0], nRD};
  116. wire reg_oe_rising = !reg_nCS_sreg[4] && (reg_oe_sreg[5:0] == 6'b000001);
  117. wire reg_oe_falling = (reg_oe_sreg[5:0] == 6'b100000);
  118. reg [7:0] reg_DP_nCS_sreg;
  119. initial reg_DP_nCS_sreg = 8'b11111111;
  120. always @(posedge CLK) reg_DP_nCS_sreg <= {reg_DP_nCS_sreg[6:0], DP_nCS};
  121. reg [5:0] reg_we_sreg;
  122. initial reg_we_sreg = 6'b111111;
  123. always @(posedge CLK) reg_we_sreg <= {reg_we_sreg[4:0], nWR};
  124. wire reg_we_rising = !reg_nCS_sreg[4] && (reg_we_sreg[5:0] == 6'b000001);
  125. wire reg_dp_we_rising = !reg_DP_nCS_sreg[5] && (reg_we_sreg[1:0] == 2'b01);
  126. wire reg_we_falling = (reg_we_sreg[1:0] == 2'b10);
  127. wire [15:0] ram_douta;
  128. wire [9:0] ram_addra;
  129. reg [7:0] DP_DOr;
  130. wire [7:0] DP_DO;
  131. wire [7:0] UPD_DO;
  132. reg ram_web;
  133. reg [10:0] ram_addrb;
  134. reg [65:0] DP_ADDRr;
  135. always @(posedge CLK) begin
  136. DP_ADDRr <= {DP_ADDRr[54:0], DP_ADDR};
  137. end
  138. always @(posedge CLK) begin
  139. ram_addrb <= DP_ADDR; //r[10:0];
  140. ram_web <= ~(nWR | reg_DP_nCS_sreg[0] | reg_DP_nCS_sreg[4]);
  141. end
  142. upd77c25_datram datram (
  143. .clka(CLK), // input clka
  144. .wea(ram_wea), // input [0 : 0] wea
  145. .addra(ram_addra), // input [9 : 0] addra
  146. .dina(ram_dina), // input [15 : 0] dina
  147. .douta(ram_douta), // output [15 : 0] douta
  148. .clkb(CLK), // input clkb
  149. .web(ram_web), // input [0 : 0] web
  150. .addrb(ram_addrb), // input [10 : 0] addrb
  151. .dinb(DI), // input [7 : 0] dinb
  152. .doutb(DP_DO) // output [7 : 0] doutb
  153. );
  154. assign ram_wea = ((op != I_JP) && op_dst == 4'b1111 && insn_state == STATE_IDLE1);
  155. assign ram_addra = {regs_dpb,
  156. regs_dph | ((insn_state == STATE_ALU1 && op_dst == 4'b1100)
  157. ? 4'b0100
  158. : 4'b0000),
  159. regs_dpl};
  160. reg signed [15:0] regs_k;
  161. reg signed [15:0] regs_l;
  162. reg [15:0] regs_trb;
  163. reg [15:0] regs_tr;
  164. reg [15:0] regs_dr;
  165. reg [15:0] regs_sr;
  166. reg [15:0] regs_si;
  167. reg [3:0] regs_sp;
  168. reg cond_true;
  169. reg [8:0] jp_brch;
  170. reg [10:0] jp_na;
  171. reg [15:0] ld_id;
  172. reg [3:0] ld_dst;
  173. wire [31:0] mul_result = regs_k * regs_l;
  174. reg [15:0] regs_m;
  175. reg [15:0] regs_n;
  176. reg [15:0] alu_p;
  177. reg [15:0] alu_q;
  178. reg [15:0] alu_r;
  179. reg [1:0] alu_store;
  180. reg [15:0] stack [15:0];
  181. reg [15:0] idb;
  182. reg [15:0] regs_ab [1:0];
  183. assign DR = regs_dr;
  184. assign SR = regs_sr;
  185. assign PC = pc;
  186. assign A = regs_ab[0];
  187. assign B = regs_ab[1];
  188. assign FL_A = {flags_s1[0],flags_s0[0],flags_c[0],flags_z[0],flags_ov1[0],flags_ov0[0]};
  189. assign FL_B = {flags_s1[1],flags_s0[1],flags_c[1],flags_z[1],flags_ov1[1],flags_ov0[1]};
  190. initial begin
  191. alu_store = 2'b11;
  192. insn_state = STATE_IDLE1;
  193. regs_sp = 4'b0000;
  194. pc = 11'b0;
  195. regs_sr = 16'b0;
  196. regs_rp = 16'h0000;
  197. regs_dpb = 2'b0;
  198. regs_dph = 4'b0;
  199. regs_dpl = 4'b0;
  200. regs_k = 16'b0;
  201. regs_l = 16'b0;
  202. regs_ab[0] = 16'b0;
  203. regs_ab[1] = 16'b0;
  204. flags_ov0 = 2'b0;
  205. flags_ov1 = 2'b0;
  206. flags_z = 2'b0;
  207. flags_c = 2'b0;
  208. flags_s0 = 2'b0;
  209. flags_s1 = 2'b0;
  210. regs_tr = 16'b0;
  211. regs_trb = 16'b0;
  212. regs_dr = 16'b0;
  213. end
  214. reg [7:0] A0r;
  215. initial A0r = 8'b11111111;
  216. always @(posedge CLK) A0r <= {A0r[6:0], A0};
  217. reg [7:0] last_op;
  218. initial last_op = 8'h00;
  219. always @(posedge CLK) begin
  220. if(RST) begin
  221. if((op_src == 4'b1000 && op[1] == 1'b0 && insn_state == STATE_STORE)
  222. || (op_dst == 4'b0110 && op != 2'b10 && insn_state == STATE_STORE)) regs_sr[SR_RQM] <= 1'b1;
  223. else if((reg_we_rising) && (A0r[3] == 1'b0)) begin
  224. if(!regs_sr[SR_DRC]) begin
  225. if(regs_sr[SR_DRS] == 1'b1) begin
  226. regs_sr[SR_RQM] <= 1'b0;
  227. end
  228. end else begin
  229. regs_sr[SR_RQM] <= 1'b0;
  230. end
  231. end
  232. else if(reg_oe_rising && (A0r[3] == 1'b0)) begin
  233. if(!regs_sr[SR_DRC]) begin
  234. if(regs_sr[SR_DRS] == 1'b1) begin
  235. regs_sr[SR_RQM] <= 1'b0;
  236. end
  237. end else begin
  238. regs_sr[SR_RQM] <= 1'b0;
  239. end
  240. end
  241. end else begin
  242. regs_sr[SR_RQM] <= 1'b0;
  243. end
  244. end
  245. always @(posedge CLK) begin
  246. if(RST) begin
  247. if(reg_we_rising && (A0r[3] == 1'b0)) begin
  248. if(!regs_sr[SR_DRC]) begin
  249. if(regs_sr[SR_DRS] == 1'b0) begin
  250. regs_sr[SR_DRS] <= 1'b1;
  251. end else begin
  252. regs_sr[SR_DRS] <= 1'b0;
  253. end
  254. end
  255. end else if(reg_oe_rising) begin
  256. case(A0r[3])
  257. 1'b0: begin
  258. if(!regs_sr[SR_DRC]) begin
  259. if(regs_sr[SR_DRS] == 1'b0) begin
  260. regs_sr[SR_DRS] <= 1'b1;
  261. end else begin
  262. regs_sr[SR_DRS] <= 1'b0;
  263. end
  264. end
  265. end
  266. endcase
  267. end
  268. end else begin
  269. regs_sr[SR_DRS] <= 1'b0;
  270. end
  271. end
  272. always @(posedge CLK) begin
  273. if(RST) begin
  274. if(reg_we_rising && (A0r[3] == 1'b0)) begin
  275. if(!regs_sr[SR_DRC]) begin
  276. if(regs_sr[SR_DRS] == 1'b0) begin
  277. regs_dr[7:0] <= DI;
  278. end else begin
  279. regs_dr[15:8] <= DI;
  280. end
  281. end else begin
  282. regs_dr[7:0] <= DI;
  283. end
  284. end else if(ld_dst == 4'b0110 && insn_state == STATE_STORE) begin
  285. if (op == I_OP || op == I_RT) regs_dr <= idb;
  286. else if (op == I_LD) regs_dr <= ld_id;
  287. end
  288. end else begin
  289. regs_dr <= 16'h0000;
  290. end
  291. end
  292. always @(posedge CLK) begin
  293. if(reg_oe_falling) DP_DOr <= DP_DO;
  294. end
  295. assign UPD_DO = (A0 ? regs_sr[15:8] : (regs_sr[SR_DRC] ? regs_dr[7:0] : (regs_sr[SR_DRS] ? regs_dr[15:8] : regs_dr[7:0])));
  296. assign DO = !DP_nCS ? DP_DOr : UPD_DO;
  297. always @(posedge CLK) begin
  298. if(RST) begin
  299. case(insn_state)
  300. STATE_FETCH: begin
  301. insn_state <= STATE_LOAD;
  302. if(op == I_OP || op == I_RT) begin
  303. if(|op_alu) begin
  304. flags_z[op_asl] <= (alu_r == 0);
  305. flags_s0[op_asl] <= alu_r[15];
  306. end
  307. case(op_alu)
  308. 4'b0001, 4'b0010, 4'b0011, 4'b1010, 4'b1101, 4'b1110, 4'b1111: begin
  309. flags_c[op_asl] <= 0;
  310. flags_ov0[op_asl] <= 0;
  311. flags_ov1[op_asl] <= 0;
  312. end
  313. 4'b0100, 4'b0101, 4'b0110, 4'b0111, 4'b1000, 4'b1001: begin
  314. if(op_alu[0]) begin
  315. flags_c[op_asl] <= (alu_r < alu_q);
  316. flags_ov0[op_asl] <= (alu_q[15] ^ alu_r[15]) & ~(alu_q[15] ^ alu_p[15]);
  317. if((alu_q[15] ^ alu_r[15]) & ~(alu_q[15] ^ alu_p[15])) begin
  318. flags_s1[op_asl] <= flags_ov1[op_asl] ^ ~alu_r[15];
  319. flags_ov1[op_asl] <= ~flags_ov1[op_asl];
  320. end
  321. end else begin
  322. flags_c[op_asl] <= (alu_r > alu_q);
  323. flags_ov0[op_asl] <= (alu_q[15] ^ alu_r[15]) & (alu_q[15] ^ alu_p[15]);
  324. if((alu_q[15] ^ alu_r[15]) & (alu_q[15] ^ alu_p[15])) begin
  325. flags_s1[op_asl] <= flags_ov1[op_asl] ^ ~alu_r[15];
  326. flags_ov1[op_asl] <= ~flags_ov1[op_asl];
  327. end
  328. end
  329. end
  330. 4'b1011: begin
  331. flags_c[op_asl] <= alu_q[0];
  332. flags_ov0[op_asl] <= 0;
  333. flags_ov1[op_asl] <= 0;
  334. end
  335. 4'b1100: begin
  336. flags_c[op_asl] <= alu_q[15];
  337. flags_ov0[op_asl] <= 0;
  338. flags_ov1[op_asl] <= 0;
  339. end
  340. endcase
  341. end
  342. opcode <= opcode_w;
  343. op <= opcode_w[23:22];
  344. op_pselect <= opcode_w[21:20];
  345. op_alu <= opcode_w[19:16];
  346. op_asl <= opcode_w[15];
  347. op_dpl <= opcode_w[14:13];
  348. op_dphm <= opcode_w[12:9];
  349. op_rpdcr <= opcode_w[8];
  350. op_src <= opcode_w[7:4];
  351. op_dst <= opcode_w[3:0];
  352. jp_brch <= opcode_w[21:13];
  353. jp_na <= opcode_w[12:2];
  354. ld_id <= opcode_w[21:6];
  355. ld_dst <= opcode_w[3:0];
  356. regs_m <= {mul_result[31], mul_result[29:15]};
  357. regs_n <= {mul_result[14:0], 1'b0};
  358. end
  359. STATE_LOAD: begin
  360. insn_state <= STATE_ALU1;
  361. case(op)
  362. I_OP, I_RT: begin
  363. case(op_src)
  364. 4'b0000: idb <= regs_trb;
  365. 4'b0001: idb <= regs_ab[0];
  366. 4'b0010: idb <= regs_ab[1];
  367. 4'b0011: idb <= regs_tr;
  368. 4'b0100: idb <= {regs_dpb,regs_dph,regs_dpl};
  369. 4'b0101: idb <= regs_rp;
  370. 4'b0110: idb <= dat_doutb; // Address: [regs_rp]
  371. 4'b0111: idb <= flags_s1[0] ? 16'h7fff : 16'h8000;
  372. 4'b1000: idb <= regs_dr;
  373. 4'b1001: idb <= regs_dr;
  374. 4'b1010: idb <= regs_sr;
  375. 4'b1101: idb <= regs_k;
  376. 4'b1110: idb <= regs_l;
  377. 4'b1111: idb <= ram_douta; // Address: [regs_dp]
  378. endcase
  379. end
  380. endcase
  381. end
  382. STATE_ALU1: begin
  383. insn_state <= STATE_STORE;
  384. case(op)
  385. I_OP, I_RT: begin
  386. alu_q <= regs_ab[op_asl];
  387. if(op_alu[3:1] == 3'b100) begin
  388. alu_p <= 16'h0001;
  389. end else begin
  390. case(op_pselect)
  391. 2'b00:
  392. alu_p <= ram_douta;
  393. 2'b01:
  394. alu_p <= idb;
  395. 2'b10:
  396. alu_p <= regs_m;
  397. 2'b11:
  398. alu_p <= regs_n;
  399. endcase
  400. end
  401. end
  402. I_JP: begin
  403. case(jp_brch)
  404. 9'b100_000_000: cond_true <= 1;
  405. 9'b101_000_000: cond_true <= 1;
  406. 9'b010_000_000: cond_true <= (flags_c[0] == 0);
  407. 9'b010_000_010: cond_true <= (flags_c[0] == 1);
  408. 9'b010_000_100: cond_true <= (flags_c[1] == 0);
  409. 9'b010_000_110: cond_true <= (flags_c[1] == 1);
  410. 9'b010_001_000: cond_true <= (flags_z[0] == 0);
  411. 9'b010_001_010: cond_true <= (flags_z[0] == 1);
  412. 9'b010_001_100: cond_true <= (flags_z[1] == 0);
  413. 9'b010_001_110: cond_true <= (flags_z[1] == 1);
  414. 9'b010_010_000: cond_true <= (flags_ov0[0] == 0);
  415. 9'b010_010_010: cond_true <= (flags_ov0[0] == 1);
  416. 9'b010_010_100: cond_true <= (flags_ov0[1] == 0);
  417. 9'b010_010_110: cond_true <= (flags_ov0[1] == 1);
  418. 9'b010_011_000: cond_true <= (flags_ov1[0] == 0);
  419. 9'b010_011_010: cond_true <= (flags_ov1[0] == 1);
  420. 9'b010_011_100: cond_true <= (flags_ov1[1] == 0);
  421. 9'b010_011_110: cond_true <= (flags_ov1[1] == 1);
  422. 9'b010_100_000: cond_true <= (flags_s0[0] == 0);
  423. 9'b010_100_010: cond_true <= (flags_s0[0] == 1);
  424. 9'b010_100_100: cond_true <= (flags_s0[1] == 0);
  425. 9'b010_100_110: cond_true <= (flags_s0[1] == 1);
  426. 9'b010_101_000: cond_true <= (flags_s1[0] == 0);
  427. 9'b010_101_010: cond_true <= (flags_s1[0] == 1);
  428. 9'b010_101_100: cond_true <= (flags_s1[1] == 0);
  429. 9'b010_101_110: cond_true <= (flags_s1[1] == 1);
  430. 9'b010_110_000: cond_true <= (regs_dpl == 0);
  431. 9'b010_110_001: cond_true <= (regs_dpl != 0);
  432. 9'b010_110_010: cond_true <= (regs_dpl == 4'b1111);
  433. 9'b010_110_011: cond_true <= (regs_dpl != 4'b1111);
  434. 9'b010_111_100: cond_true <= (regs_sr[SR_RQM] == 0);
  435. 9'b010_111_110: cond_true <= (regs_sr[SR_RQM] == 1);
  436. default: cond_true <= 0;
  437. endcase
  438. end
  439. endcase
  440. end
  441. // STATE_ALU2: begin
  442. //insn_state <= STATE_STORE;
  443. // end
  444. STATE_STORE: begin
  445. insn_state <= STATE_IDLE1;
  446. if(op[1] == 1'b0) begin
  447. case(op_alu)
  448. 4'b0001: alu_r <= alu_q | alu_p;
  449. 4'b0010: alu_r <= alu_q & alu_p;
  450. 4'b0011: alu_r <= alu_q ^ alu_p;
  451. 4'b0100: alu_r <= alu_q - alu_p;
  452. 4'b0101: alu_r <= alu_q + alu_p;
  453. 4'b0110: alu_r <= alu_q - alu_p - flags_c[~op_asl];
  454. 4'b0111: alu_r <= alu_q + alu_p + flags_c[~op_asl];
  455. 4'b1000: alu_r <= alu_q - alu_p;
  456. 4'b1001: alu_r <= alu_q + alu_p;
  457. 4'b1010: alu_r <= ~alu_q;
  458. 4'b1011: alu_r <= {alu_q[15], alu_q[15:1]};
  459. 4'b1100: alu_r <= {alu_q[14:0], flags_c[~op_asl]};
  460. 4'b1101: alu_r <= {alu_q[13:0], 2'b11};
  461. 4'b1110: alu_r <= {alu_q[11:0], 4'b1111};
  462. 4'b1111: alu_r <= {alu_q[7:0], alu_q[15:8]};
  463. endcase
  464. end
  465. case(op)
  466. I_OP, I_RT: begin
  467. case(op_dst)
  468. 4'b0001: begin
  469. regs_ab[0] <= idb;
  470. alu_store <= 2'b10;
  471. end
  472. 4'b0010: begin
  473. regs_ab[1] <= idb;
  474. alu_store <= 2'b01;
  475. end
  476. 4'b0011: regs_tr <= idb;
  477. 4'b0100: {regs_dpb,regs_dph,regs_dpl} <= idb[9:0];
  478. 4'b0101: regs_rp <= idb;
  479. // 4'b0110: regs_dr <= idb;
  480. 4'b0111: begin
  481. regs_sr[14] <= idb[14];
  482. regs_sr[13] <= idb[13];
  483. regs_sr[11] <= idb[11];
  484. regs_sr[SR_DRC] <= idb[10];
  485. regs_sr[9] <= idb[9];
  486. regs_sr[8] <= idb[8];
  487. regs_sr[7] <= idb[7];
  488. regs_sr[1] <= idb[1];
  489. regs_sr[0] <= idb[0];
  490. end
  491. 4'b1010: regs_k <= idb;
  492. 4'b1011: begin
  493. regs_k <= idb;
  494. regs_l <= dat_doutb;
  495. end
  496. 4'b1100: begin
  497. regs_k <= ram_douta;
  498. regs_l <= idb;
  499. end
  500. 4'b1101: regs_l <= idb;
  501. 4'b1110: regs_trb <= idb;
  502. 4'b1111: ram_dina_r <= idb;
  503. endcase
  504. end
  505. I_LD: begin
  506. case(ld_dst)
  507. 4'b0001: regs_ab[0] <= ld_id;
  508. 4'b0010: regs_ab[1] <= ld_id;
  509. 4'b0011: regs_tr <= ld_id;
  510. 4'b0100: {regs_dpb,regs_dph,regs_dpl} <= ld_id[9:0];
  511. 4'b0101: regs_rp <= ld_id;
  512. // 4'b0110: regs_dr <= ld_id;
  513. 4'b0111: begin
  514. regs_sr[14] <= ld_id[14];
  515. regs_sr[13] <= ld_id[13];
  516. regs_sr[11] <= ld_id[11];
  517. regs_sr[SR_DRC] <= ld_id[10];
  518. regs_sr[9] <= ld_id[9];
  519. regs_sr[8] <= ld_id[8];
  520. regs_sr[7] <= ld_id[7];
  521. regs_sr[1] <= ld_id[1];
  522. regs_sr[0] <= ld_id[0];
  523. end
  524. 4'b1010: regs_k <= ld_id;
  525. 4'b1011: begin
  526. regs_k <= ld_id;
  527. regs_l <= dat_doutb;
  528. end
  529. 4'b1100: begin
  530. regs_k <= ram_douta;
  531. regs_l <= ld_id;
  532. end
  533. 4'b1101: regs_l <= ld_id;
  534. 4'b1110: regs_trb <= ld_id;
  535. 4'b1111: ram_dina_r <= ld_id;
  536. endcase
  537. end
  538. endcase
  539. case(op)
  540. I_OP, I_RT: begin
  541. if(op_rpdcr) regs_rp <= regs_rp - 1;
  542. if(op == I_OP) pc <= pc + 1;
  543. else begin
  544. pc <= stack[regs_sp-1];
  545. regs_sp <= regs_sp - 1;
  546. end
  547. end
  548. I_JP: begin
  549. if(cond_true) begin
  550. pc <= jp_na;
  551. if(jp_brch[8:6] == 3'b101) begin
  552. stack[regs_sp] <= pc + 1;
  553. regs_sp <= regs_sp + 1;
  554. end
  555. end else pc <= pc + 1;
  556. end
  557. I_LD: begin
  558. pc <= pc + 1;
  559. end
  560. endcase
  561. end
  562. // STATE_NEXT: begin
  563. // insn_state <= STATE_IDLE1;
  564. // end
  565. STATE_IDLE1: begin
  566. insn_state <= STATE_FETCH;
  567. case(op)
  568. I_OP, I_RT: begin
  569. case(op_dpl)
  570. 2'b01: regs_dpl <= regs_dpl + 1;
  571. 2'b10: regs_dpl <= regs_dpl - 1;
  572. 2'b11: regs_dpl <= 4'b0000;
  573. endcase
  574. regs_dph <= regs_dph ^ op_dphm;
  575. if(|op_alu && alu_store[op_asl]) regs_ab[op_asl] <= alu_r;
  576. alu_store <= 2'b11;
  577. end
  578. endcase
  579. end
  580. endcase
  581. end else begin
  582. insn_state <= STATE_IDLE1;
  583. pc <= 11'b0;
  584. regs_sp <= 4'b0000;
  585. cond_true <= 0;
  586. regs_sr[14] <= 0;
  587. regs_sr[13] <= 0;
  588. regs_sr[11] <= 0;
  589. regs_sr[SR_DRC] <= 0;
  590. regs_sr[9] <= 0;
  591. regs_sr[8] <= 0;
  592. regs_sr[7] <= 0;
  593. regs_rp <= 16'h0000;
  594. regs_dpb <= 2'b0;
  595. regs_dph <= 4'b0;
  596. regs_dpl <= 4'b0;
  597. regs_k <= 16'b0;
  598. regs_l <= 16'b0;
  599. regs_ab[0] <= 16'b0;
  600. regs_ab[1] <= 16'b0;
  601. flags_ov0 <= 2'b0;
  602. flags_ov1 <= 2'b0;
  603. flags_z <= 2'b0;
  604. flags_c <= 2'b0;
  605. flags_s0 <= 2'b0;
  606. flags_s1 <= 2'b0;
  607. regs_tr <= 16'b0;
  608. regs_trb <= 16'b0;
  609. opcode <= 23'b0;
  610. op_pselect <= 2'b0;
  611. op_alu <= 4'b0;
  612. op_asl <= 1'b0;
  613. op_dpl <= 2'b0;
  614. op_dphm <= 4'b0;
  615. op_rpdcr <= 1'b0;
  616. op_src <= 4'b0;
  617. op_dst <= 4'b0;
  618. jp_brch <= 9'b0;
  619. jp_na <= 11'b0;
  620. ld_id <= 16'b0;
  621. ld_dst <= 4'b0;
  622. regs_m <= 16'b0;
  623. regs_n <= 16'b0;
  624. end
  625. end
  626. endmodule