upd77c25.v 19 KB

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