sam.sv 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. //
  2. // 7474 flip flop emulation using a fast clock to emulate asynchronous logic
  3. //
  4. module ff_7474s
  5. #(
  6. parameter logic init = 1'b1
  7. )
  8. (
  9. input fast_clk,
  10. input d,
  11. input c,
  12. input s_n,
  13. input r_n,
  14. output q_p,
  15. output q_n
  16. );
  17. reg c_q = 1'b1;
  18. wire strobe = c & ~c_q;
  19. // Handle the transient state, too (R# = S# = 0 => Q = Q# = 1)
  20. reg q;
  21. wire transient = ~r_n & ~s_n;
  22. assign q_p = q | transient;
  23. assign q_n = ~q | transient;
  24. always @(posedge fast_clk)
  25. begin
  26. // Clock edge detect
  27. c_q <= c;
  28. if (~r_n)
  29. q <= 1'b0;
  30. else if (~s_n)
  31. q <= 1'b1;
  32. else if (strobe)
  33. q <= d;
  34. end
  35. endmodule // ff_7474s
  36. //
  37. // 74393 counter emulation using a fast clock to emulate a gated ripple clock
  38. //
  39. module ctr_74393s
  40. #(
  41. parameter bits = 4
  42. )
  43. (
  44. input fast_clk,
  45. input cp_n,
  46. input mr,
  47. output reg [bits-1:0] q
  48. );
  49. reg cp_n_q = 1'b0; // Edge detect
  50. wire strobe = cp_n_q & ~cp_n;
  51. always @(posedge fast_clk)
  52. begin
  53. cp_n_q <= cp_n;
  54. if (mr) // Asynchronous reset
  55. q <= 'b0;
  56. else
  57. q <= q + strobe;
  58. end
  59. endmodule // ctr_74393s
  60. //
  61. // 74155 decoder emulation
  62. //
  63. module dc_74155 #(
  64. parameter bits = 2,
  65. parameter outs = 1 << bits
  66. ) (
  67. input e,
  68. input [bits-1:0] a,
  69. output reg [outs-1:0] q_n
  70. );
  71. always_comb
  72. begin
  73. for (int i = 0; i < outs; i++)
  74. begin
  75. logic [bits-1:0] ii;
  76. ii = i;
  77. q_n[i] = ~(e && a == ii);
  78. ii++;
  79. end
  80. end
  81. endmodule // dc_74155
  82. //
  83. // Smartaid Magnum asynchronous ROM
  84. // Open-coded to allow synthesis as random logic
  85. //
  86. module samu15 (
  87. input [8:0] a,
  88. output reg [3:0] q
  89. );
  90. always_comb
  91. casez (a[5:0])
  92. 6'b0100_00: q = { 2'b11, ~a[6], 1'b1 }; // F, D
  93. 6'b0100_?1: q = 4'b1001; // 9
  94. 6'b0100_10: q = { 3'b100, a[8:7] == 2'b10 }; // 8, 9
  95. 6'b0101_0?: q = 4'b1110; // E
  96. 6'b0110_00: q = ~a[6] ? 4'hD : 4'h4; // D, 4
  97. 6'b0111_10: q = { 3'b110, a[8:7] != 2'b10 }; // D, C
  98. default: q = 4'b0100; // 4
  99. endcase // casez (a[5:0])
  100. endmodule // samu15
  101. //
  102. // Smartaid Magnum; SRAM not included
  103. //
  104. module samagnum (
  105. input fast_clk,
  106. input stb_50us, // ~50 us fast_clk strobe
  107. input clk,
  108. input xmemwr_n,
  109. input xmemfl_n,
  110. output xmemfl_out_n,
  111. output resin_n,
  112. input [15:0] a, // Address from ABC-bus
  113. output reg [15:0] a_out, // Possibly modified address
  114. output a_map, // Use this map
  115. output [7:0] dout,
  116. output dout_oe // Use the data from dout
  117. );
  118. wire out_dir; // "Real life" bus switch (0 = out)
  119. wire sram_we = xmemwr_n;
  120. wire sram_oe;
  121. wire sram_ce;
  122. wire pwrgood_n = 1'b0; // From Q1/Q2
  123. wire [1:0] eprom_ce;
  124. wire eprom_oe;
  125. wire [8:0] prom_a;
  126. wire [3:0] prom_q;
  127. assign prom_a[5:0] = a[15:10];
  128. wire bank_sel;
  129. wire [1:0] bank;
  130. // Memory address translation (the actual memory is external)
  131. assign a_map = (~xmemfl_n & ~out_dir) | (~sram_ce & ~sram_oe);
  132. always_comb
  133. begin
  134. a_out = a;
  135. if (a_map)
  136. begin
  137. a_out[15:14] = bank;
  138. if (~eprom_ce[1])
  139. a_out[13:10] = 4'b1110;
  140. else if (~sram_ce)
  141. a_out[13:11] = 3'b010;
  142. else if (~eprom_ce[0])
  143. a_out[13:12] = 2'b00;
  144. end
  145. end // always_comb
  146. wire [7:0] u5_q;
  147. wire [3:0] u7a_qn;
  148. wire [3:0] u7b_qn;
  149. wire nor_in_9_2;
  150. wire nor_in_10_2;
  151. wire nor_in_12_1;
  152. wire u6d5a_q, u6d5a_qn;
  153. wire u6d5b_q, u6d5b_qn;
  154. wire u9e2l1a_q, u9e2l1a_qn;
  155. wire u9e2l1b_q, u9e2l1b_qn;
  156. wire u9e2h1a_q, u9e2h1a_qn;
  157. wire u9e2h1b_q, u9e2h1b_qn;
  158. wire u9e3a_q, u9e3a_qn;
  159. wire u9e3b_q, u9e3b_qn;
  160. // U3 74LS245
  161. // Emulated using an output enable
  162. assign dout_oe = ~out_dir & (~&eprom_ce | eprom_oe) & (~sram_ce | sram_oe);
  163. // U4 74LS126
  164. // Emulated by using OR with the tristate component
  165. assign dout[7:5] = 3'b111;
  166. assign dout[4] = ~nor_out2 | u5_q[2]; // U4A
  167. assign dout[3] = ~nor_out2 | u5_q[3]; // U4C
  168. assign dout[2] = ~nor_out2 | u5_q[1]; // U4B
  169. assign dout[1] = 1'b1;
  170. assign dout[0] = ~nor_out2 | u5_q[4]; // U4D
  171. // U5 74LS393
  172. ctr_74393s u5a(.fast_clk(fast_clk),
  173. .cp_n(clk), .mr(u9e3a_q), .q(u5_q[3:0]));
  174. ctr_74393s u5b(.fast_clk(fast_clk),
  175. .cp_n(u5_q[3]), .mr(u10c), .q(u5_q[7:4]));
  176. // U7 74LS155
  177. dc_74155 u7a(.e(prom_q[3]), .a(prom_q[1:0]), .q_n(u7a_qn));
  178. dc_74155 u7b(.e(~sram_we), .a(prom_q[1:0]), .q_n(u7b_qn));
  179. assign eprom_ce[1] = u7a_qn[0]; // 64 kbit
  180. assign eprom_ce[0] = u7a_qn[1]; // 128 kbit
  181. assign bank_sel = u7b_qn[3];
  182. // U9 74LS260
  183. wire u9a = ~(a[5] | a[7] | a[8] | a[9] | nor_in_12_1);
  184. wire u9b = ~(xmemfl_n | nor_in_9_2 | nor_in_10_2 | prom_q[2]);
  185. wire nor_out2 = u9b;
  186. // U10 74LS00
  187. wire u10a = ~prom_q[3];
  188. wire u10b = ~(u5_q[2] & u5_q[4]);
  189. wire u10c = ~(u9e3b_qn & u9e3a_qn);
  190. wire u10d = ~(a[6] & u9a);
  191. assign prom_a[6] = u10d;
  192. // U11 74LS32
  193. wire u11a = prom_q[3] | xmemfl_n;
  194. wire u11b = nor_out2 | xmemfl_n;
  195. wire u11c = xmemfl_n | u10a;
  196. wire u11d = prom_q[2] | xmemfl_n;
  197. assign xmemfl_out_n = u11a;
  198. assign eprom_oe = u11b;
  199. // U12 74LS08
  200. // This is an RC delay in the original; emulated here using
  201. // an up/down counter
  202. reg [2:0] u12b_rc_ctr = 3'd7;
  203. reg u12b_rc = 1'b1;
  204. wire u12b_rc_in = u9e2l1b_q;
  205. always @(posedge fast_clk)
  206. if (stb_50us)
  207. begin
  208. if (u12b_rc_in & ~u12b_rc)
  209. begin
  210. if (&u12b_rc_ctr)
  211. u12b_rc <= 1'b1;
  212. else
  213. u12b_rc_ctr <= u12b_rc_ctr + 1'b1;
  214. end
  215. else if (~u12b_rc_in & u12b_rc)
  216. begin
  217. if (~|u12b_rc_ctr)
  218. u12b_rc <= 1'b0;
  219. else
  220. u12b_rc_ctr <= u12b_rc_ctr - 1'b1;
  221. end
  222. end
  223. //wire u12a = xmemfl_n & xmemfl_out_n; // Dead
  224. wire u12b = u12b_rc & u9e3b_q;
  225. wire u12c = u11c;
  226. //wire u12d = 1'bx; // Unconnected
  227. assign out_dir = u12c;
  228. // U13 74HC32 (HC!)
  229. wire u13a = pwrgood_n | u7a_qn[2];
  230. //wire u13b = sram_we; // Dead
  231. //wire u13c = pwrgood_n; // Dead
  232. wire u13d = pwrgood_n | xmemfl_n;
  233. assign sram_ce = u13a;
  234. assign sram_oe = u13d;
  235. // U15 82S131 decode PROM
  236. assign prom_a[8:7] = bank;
  237. samu15 u15 (.a(prom_a), .q(prom_q));
  238. // U6_D5 74LS74
  239. ff_7474s u6d5a(.fast_clk (fast_clk),
  240. .d (xmemfl_n), .c (clk), .s_n (u9e3b_q), .r_n (1'b1),
  241. .q_p(u6d5a_q), .q_n ());
  242. assign nor_in_10_2 = u6d5a_q;
  243. ff_7474s u6d5b(.fast_clk (fast_clk),
  244. .d (nor_in_10_2), .c (clk), .s_n (u9e3b_q), .r_n (1'b1),
  245. .q_p (u6d5b_q), .q_n());
  246. assign nor_in_9_2 = u6d5b_q;
  247. wire reset_bank = 1'b1;
  248. // U9_E2_L1 74LS74
  249. ff_7474s u9e2l1a(.fast_clk (fast_clk),
  250. .d(a[1]), .c(bank_sel), .s_n(1'b1), .r_n(reset_bank),
  251. .q_p(u9e2l1a_q), .q_n());
  252. assign bank[1] = u9e2l1a_q;
  253. ff_7474s u9e2l1b(.fast_clk (fast_clk),
  254. .d(clk), .c(u11d), .s_n(u12b), .r_n(1'b1),
  255. .q_p(u9e2l1b_q), .q_n(u9e2l1b_qn));
  256. assign resin_n = ~u9e2l1b_qn;
  257. // U9_E2_H1 74LS74
  258. ff_7474s u9e2h1a(.fast_clk (fast_clk),
  259. .d(a[0]), .c(bank_sel), .s_n(1'b1), .r_n(reset_bank),
  260. .q_p(u9e2h1a_q), .q_n());
  261. assign bank[0] = u9e2h1a_q;
  262. // U9_E2_H1B unconnected
  263. // U9_E3 74LS74
  264. ff_7474s u9e3a(.fast_clk (fast_clk),
  265. .d(clk), .c(u11d), .s_n(1'b1), .r_n(clk),
  266. .q_p(u9e3a_q), .q_n(u9e3a_qn));
  267. ff_7474s u9e3b(.fast_clk (fast_clk),
  268. .d(1'b0), .c(u9e3a_q), .s_n(u10b), .r_n(1'b1),
  269. .q_p(u9e3b_q), .q_n(u9e3b_qn));
  270. assign nor_in_12_1 = u9e3b_qn;
  271. endmodule // samagnum